From a27c93f47cae09cf76179e4a3d78b23a6e4a7be5 Mon Sep 17 00:00:00 2001 From: Bart De Neuter Date: Fri, 5 Aug 2016 23:14:58 +0200 Subject: [PATCH] cleanup + custom Mindstorms plugin --- build.gradle | 15 - dbusjava/build.gradle | 4 - .../lejos/internal/io/NativeDomainSocket.java | 197 -- .../lejos/internal/io/SocketInputStream.java | 37 - .../lejos/internal/io/SocketOutputStream.java | 26 - .../java/lejos/internal/io/package-info.java | 8 - ev3classes/build.gradle | 4 - .../src/main/java/lejos/hardware/Audio.java | 96 - .../src/main/java/lejos/hardware/Battery.java | 21 - .../main/java/lejos/hardware/Bluetooth.java | 53 - .../lejos/hardware/BluetoothException.java | 29 - .../src/main/java/lejos/hardware/Brick.java | 107 - .../main/java/lejos/hardware/BrickFinder.java | 331 --- .../main/java/lejos/hardware/BrickInfo.java | 25 - .../src/main/java/lejos/hardware/Button.java | 228 -- .../src/main/java/lejos/hardware/Device.java | 45 - .../java/lejos/hardware/DeviceException.java | 33 - .../src/main/java/lejos/hardware/Key.java | 32 - .../main/java/lejos/hardware/KeyListener.java | 9 - .../src/main/java/lejos/hardware/Keys.java | 45 - .../src/main/java/lejos/hardware/LED.java | 7 - .../java/lejos/hardware/ListenerCaller.java | 9 - .../java/lejos/hardware/LocalBTDevice.java | 173 -- .../java/lejos/hardware/LocalWifiDevice.java | 112 - .../src/main/java/lejos/hardware/Power.java | 34 - .../java/lejos/hardware/RemoteBTDevice.java | 37 - .../src/main/java/lejos/hardware/Sound.java | 221 -- .../src/main/java/lejos/hardware/Sounds.java | 19 - .../src/main/java/lejos/hardware/Wifi.java | 32 - .../java/lejos/hardware/device/DLight.java | 107 - .../java/lejos/hardware/device/DLights.java | 431 --- .../hardware/device/DeviceIdentifier.java | 308 --- .../java/lejos/hardware/device/IRLink.java | 225 -- .../lejos/hardware/device/IRTransmitter.java | 40 - .../java/lejos/hardware/device/LDCMotor.java | 78 - .../java/lejos/hardware/device/LMotor.java | 226 -- .../main/java/lejos/hardware/device/LSC.java | 226 -- .../java/lejos/hardware/device/LServo.java | 160 -- .../hardware/device/LnrActrFirgelliNXT.java | 358 --- .../java/lejos/hardware/device/MMXMotor.java | 103 - .../hardware/device/MMXRegulatedMotor.java | 230 -- .../main/java/lejos/hardware/device/MSC.java | 138 - .../java/lejos/hardware/device/MServo.java | 147 -- .../hardware/device/MindSensorsNumPad.java | 269 -- .../java/lejos/hardware/device/NXTCam.java | 152 -- .../java/lejos/hardware/device/NXTMMX.java | 620 ----- .../main/java/lejos/hardware/device/NXTe.java | 82 - .../java/lejos/hardware/device/PFLink.java | 246 -- .../java/lejos/hardware/device/PFMate.java | 125 - .../lejos/hardware/device/PFMateMotor.java | 141 - .../lejos/hardware/device/PFMotorPort.java | 47 - .../hardware/device/PSPNXController.java | 172 -- .../java/lejos/hardware/device/RCXLink.java | 255 -- .../hardware/device/RCXMotorMultiplexer.java | 68 - .../hardware/device/RCXPlexedMotorPort.java | 51 - .../hardware/device/RCXSensorMultiplexer.java | 98 - .../java/lejos/hardware/device/SensorMux.java | 150 -- .../java/lejos/hardware/device/TouchMUX.java | 189 -- .../main/java/lejos/hardware/device/UART.java | 168 -- .../lejos/hardware/device/package-info.java | 5 - .../tetrix/TetrixControllerFactory.java | 136 - .../device/tetrix/TetrixEncoderMotor.java | 84 - .../hardware/device/tetrix/TetrixMotor.java | 70 - .../device/tetrix/TetrixMotorController.java | 584 ----- .../device/tetrix/TetrixRegulatedMotor.java | 195 -- .../hardware/device/tetrix/TetrixServo.java | 95 - .../device/tetrix/TetrixServoController.java | 303 --- .../hardware/device/tetrix/package-info.java | 15 - .../src/main/java/lejos/hardware/ev3/EV3.java | 8 - .../java/lejos/hardware/ev3/LocalEV3.java | 227 -- .../java/lejos/hardware/ev3/package-info.java | 4 - .../java/lejos/hardware/gps/Coordinates.java | 571 ---- .../java/lejos/hardware/gps/GGASentence.java | 290 --- .../src/main/java/lejos/hardware/gps/GPS.java | 182 -- .../java/lejos/hardware/gps/GPSListener.java | 24 - .../java/lejos/hardware/gps/GSASentence.java | 195 -- .../java/lejos/hardware/gps/GSVSentence.java | 260 -- .../java/lejos/hardware/gps/NMEASentence.java | 109 - .../java/lejos/hardware/gps/RMCSentence.java | 289 --- .../java/lejos/hardware/gps/Satellite.java | 153 -- .../java/lejos/hardware/gps/SimpleGPS.java | 381 --- .../java/lejos/hardware/gps/VTGSentence.java | 98 - .../java/lejos/hardware/gps/package-info.java | 8 - .../java/lejos/hardware/lcd/CommonLCD.java | 120 - .../main/java/lejos/hardware/lcd/Font.java | 2304 ----------------- .../java/lejos/hardware/lcd/GraphicsLCD.java | 359 --- .../main/java/lejos/hardware/lcd/Image.java | 198 -- .../src/main/java/lejos/hardware/lcd/LCD.java | 307 --- .../lejos/hardware/lcd/LCDOutputStream.java | 71 - .../main/java/lejos/hardware/lcd/TextLCD.java | 86 - .../java/lejos/hardware/lcd/package-info.java | 4 - .../hardware/motor/BaseRegulatedMotor.java | 429 --- .../java/lejos/hardware/motor/BasicMotor.java | 94 - .../motor/EV3LargeRegulatedMotor.java | 44 - .../motor/EV3MediumRegulatedMotor.java | 44 - .../hardware/motor/JavaMotorRegulator.java | 595 ----- .../MindsensorsGlideWheelMRegulatedMotor.java | 51 - ...MindsensorsGlideWheelXLRegulatedMotor.java | 47 - .../main/java/lejos/hardware/motor/Motor.java | 49 - .../lejos/hardware/motor/MotorRegulator.java | 148 -- .../hardware/motor/NXTRegulatedMotor.java | 43 - .../java/lejos/hardware/motor/RCXMotor.java | 24 - .../java/lejos/hardware/motor/Tachometer.java | 17 - .../hardware/motor/UnregulatedMotor.java | 70 - .../lejos/hardware/motor/package-info.java | 6 - .../java/lejos/hardware/package-info.java | 4 - .../java/lejos/hardware/port/AnalogPort.java | 30 - .../lejos/hardware/port/BasicMotorPort.java | 29 - .../lejos/hardware/port/BasicSensorPort.java | 48 - .../hardware/port/ConfigurationPort.java | 22 - .../lejos/hardware/port/I2CException.java | 25 - .../java/lejos/hardware/port/I2CPort.java | 30 - .../main/java/lejos/hardware/port/IOPort.java | 32 - .../lejos/hardware/port/LegacySensorPort.java | 14 - .../java/lejos/hardware/port/MotorPort.java | 34 - .../main/java/lejos/hardware/port/Port.java | 24 - .../lejos/hardware/port/PortException.java | 31 - .../java/lejos/hardware/port/SensorPort.java | 16 - .../lejos/hardware/port/TachoMotorPort.java | 18 - .../java/lejos/hardware/port/UARTPort.java | 103 - .../lejos/hardware/port/package-info.java | 4 - .../lejos/hardware/sensor/AnalogSensor.java | 94 - .../lejos/hardware/sensor/BaseSensor.java | 125 - .../lejos/hardware/sensor/CodeTemplate.java | 132 - .../lejos/hardware/sensor/CruizcoreGyro.java | 307 --- .../hardware/sensor/DexterCompassSensor.java | 358 --- .../hardware/sensor/DexterGPSSensor.java | 280 -- .../hardware/sensor/DexterIMUSensor.java | 379 --- .../hardware/sensor/DexterLaserSensor.java | 181 -- .../sensor/DexterPressureSensor250.java | 138 - .../sensor/DexterPressureSensor500.java | 124 - .../sensor/DexterThermalIRSensor.java | 230 -- .../lejos/hardware/sensor/EV3ColorSensor.java | 319 --- .../lejos/hardware/sensor/EV3GyroSensor.java | 225 -- .../lejos/hardware/sensor/EV3IRSensor.java | 237 -- .../hardware/sensor/EV3SensorConstants.java | 68 - .../lejos/hardware/sensor/EV3TouchSensor.java | 113 - .../hardware/sensor/EV3UltrasonicSensor.java | 191 -- .../sensor/HiTechnicAccelerometer.java | 163 -- .../hardware/sensor/HiTechnicAngleSensor.java | 209 -- .../hardware/sensor/HiTechnicBarometer.java | 201 -- .../hardware/sensor/HiTechnicColorSensor.java | 179 -- .../hardware/sensor/HiTechnicCompass.java | 225 -- .../lejos/hardware/sensor/HiTechnicEOPD.java | 145 -- .../lejos/hardware/sensor/HiTechnicGyro.java | 113 - .../hardware/sensor/HiTechnicIRSeeker.java | 107 - .../hardware/sensor/HiTechnicIRSeekerV2.java | 148 -- .../sensor/HiTechnicMagneticSensor.java | 108 - .../java/lejos/hardware/sensor/I2CSensor.java | 293 --- .../sensor/MindSensorsPressureSensor.java | 112 - .../sensor/MindsensorsAbsoluteIMU.java | 363 --- .../sensor/MindsensorsAccelerometer.java | 164 -- .../hardware/sensor/MindsensorsBTSense.java | 501 ---- .../hardware/sensor/MindsensorsCompass.java | 223 -- .../sensor/MindsensorsDistanceSensorV2.java | 215 -- .../sensor/MindsensorsLightSensorArray.java | 170 -- .../sensor/MindsensorsLineLeader.java | 165 -- .../lejos/hardware/sensor/NXTColorSensor.java | 319 --- .../lejos/hardware/sensor/NXTLightSensor.java | 166 -- .../lejos/hardware/sensor/NXTSoundSensor.java | 134 - .../lejos/hardware/sensor/NXTTouchSensor.java | 101 - .../hardware/sensor/NXTUltrasonicSensor.java | 237 -- .../lejos/hardware/sensor/RCXLightSensor.java | 146 -- .../hardware/sensor/RCXRotationSensor.java | 160 -- .../lejos/hardware/sensor/RCXThermometer.java | 87 - .../lejos/hardware/sensor/RFIDSensor.java | 268 -- .../hardware/sensor/SensorConstants.java | 61 - .../lejos/hardware/sensor/SensorMode.java | 15 - .../lejos/hardware/sensor/SensorModes.java | 56 - .../lejos/hardware/sensor/SumoEyesSensor.java | 101 - .../lejos/hardware/sensor/UARTSensor.java | 92 - .../lejos/hardware/sensor/package-info.java | 7 - .../main/java/lejos/hardware/video/Video.java | 67 - .../java/lejos/hardware/video/VideoUtils.java | 9 - .../java/lejos/hardware/video/YUYVImage.java | 120 - .../lejos/hardware/video/package-info.java | 4 - .../java/lejos/internal/dbus/Adapter.java | 105 - .../main/java/lejos/internal/dbus/Agent.java | 76 - .../java/lejos/internal/dbus/DBusBluez.java | 190 -- .../lejos/internal/dbus/DBusProperties.java | 148 -- .../main/java/lejos/internal/dbus/Device.java | 100 - .../java/lejos/internal/dbus/Manager.java | 13 - .../java/lejos/internal/dbus/PinAgent.java | 50 - .../lejos/internal/dbus/package-info.java | 4 - .../lejos/internal/ev3/EV3AnalogPort.java | 410 --- .../java/lejos/internal/ev3/EV3Audio.java | 565 ---- .../java/lejos/internal/ev3/EV3Battery.java | 68 - .../internal/ev3/EV3ConfigurationPort.java | 86 - .../lejos/internal/ev3/EV3GraphicsLCD.java | 1070 -------- .../java/lejos/internal/ev3/EV3I2CPort.java | 154 -- .../java/lejos/internal/ev3/EV3IOPort.java | 143 - .../main/java/lejos/internal/ev3/EV3Key.java | 107 - .../main/java/lejos/internal/ev3/EV3Keys.java | 225 -- .../main/java/lejos/internal/ev3/EV3LCD.java | 388 --- .../lejos/internal/ev3/EV3LCDManager.java | 330 --- .../main/java/lejos/internal/ev3/EV3LED.java | 33 - .../java/lejos/internal/ev3/EV3MotorPort.java | 825 ------ .../main/java/lejos/internal/ev3/EV3Port.java | 78 - .../java/lejos/internal/ev3/EV3TextLCD.java | 143 - .../java/lejos/internal/ev3/EV3UARTPort.java | 722 ------ .../java/lejos/internal/ev3/EV3Video.java | 102 - .../java/lejos/internal/ev3/EV3Wrapper.java | 201 -- .../java/lejos/internal/ev3/package-info.java | 4 - .../java/lejos/internal/io/NativeDevice.java | 42 - .../java/lejos/internal/io/NativeFile.java | 244 -- .../java/lejos/internal/io/NativeHCI.java | 203 -- .../java/lejos/internal/io/NativeSocket.java | 114 - .../java/lejos/internal/io/NativeWifi.java | 294 --- .../main/java/lejos/internal/io/Settings.java | 38 - .../lejos/internal/io/SystemSettings.java | 34 - .../java/lejos/internal/io/package-info.java | 4 - .../main/java/lejos/remote/ev3/EV3Reply.java | 25 - .../java/lejos/remote/ev3/EV3Request.java | 193 -- .../src/main/java/lejos/remote/ev3/Menu.java | 46 - .../main/java/lejos/remote/ev3/MenuReply.java | 14 - .../java/lejos/remote/ev3/MenuRequest.java | 39 - .../java/lejos/remote/ev3/RMIAnalogPort.java | 18 - .../main/java/lejos/remote/ev3/RMIAudio.java | 96 - .../java/lejos/remote/ev3/RMIBattery.java | 31 - .../java/lejos/remote/ev3/RMIBluetooth.java | 19 - .../main/java/lejos/remote/ev3/RMIEV3.java | 44 - .../java/lejos/remote/ev3/RMIGraphicsLCD.java | 96 - .../java/lejos/remote/ev3/RMII2CPort.java | 27 - .../main/java/lejos/remote/ev3/RMIKey.java | 30 - .../main/java/lejos/remote/ev3/RMIKeys.java | 34 - .../main/java/lejos/remote/ev3/RMILCD.java | 20 - .../main/java/lejos/remote/ev3/RMILED.java | 10 - .../main/java/lejos/remote/ev3/RMIMenu.java | 52 - .../java/lejos/remote/ev3/RMIMotorPort.java | 37 - .../lejos/remote/ev3/RMIRegulatedMotor.java | 154 -- .../lejos/remote/ev3/RMIRemoteAnalogPort.java | 45 - .../java/lejos/remote/ev3/RMIRemoteAudio.java | 68 - .../lejos/remote/ev3/RMIRemoteBattery.java | 34 - .../lejos/remote/ev3/RMIRemoteBluetooth.java | 58 - .../java/lejos/remote/ev3/RMIRemoteEV3.java | 114 - .../remote/ev3/RMIRemoteGraphicsLCD.java | 227 -- .../lejos/remote/ev3/RMIRemoteI2CPort.java | 37 - .../java/lejos/remote/ev3/RMIRemoteKey.java | 57 - .../java/lejos/remote/ev3/RMIRemoteKeys.java | 81 - .../java/lejos/remote/ev3/RMIRemoteLCD.java | 44 - .../java/lejos/remote/ev3/RMIRemoteLED.java | 21 - .../lejos/remote/ev3/RMIRemoteMotorPort.java | 45 - .../remote/ev3/RMIRemoteRegulatedMotor.java | 151 -- .../remote/ev3/RMIRemoteSampleProvider.java | 50 - .../lejos/remote/ev3/RMIRemoteTextLCD.java | 137 - .../lejos/remote/ev3/RMIRemoteUARTPort.java | 98 - .../java/lejos/remote/ev3/RMIRemoteWifi.java | 25 - .../lejos/remote/ev3/RMISampleProvider.java | 10 - .../java/lejos/remote/ev3/RMITextLCD.java | 56 - .../java/lejos/remote/ev3/RMIUARTPort.java | 107 - .../main/java/lejos/remote/ev3/RMIWifi.java | 12 - .../lejos/remote/ev3/RemoteAnalogPort.java | 108 - .../java/lejos/remote/ev3/RemoteAudio.java | 105 - .../java/lejos/remote/ev3/RemoteBattery.java | 50 - .../main/java/lejos/remote/ev3/RemoteEV3.java | 199 -- .../lejos/remote/ev3/RemoteGraphicsLCD.java | 369 --- .../java/lejos/remote/ev3/RemoteI2CPort.java | 58 - .../java/lejos/remote/ev3/RemoteIOPort.java | 79 - .../main/java/lejos/remote/ev3/RemoteKey.java | 103 - .../java/lejos/remote/ev3/RemoteKeys.java | 169 -- .../main/java/lejos/remote/ev3/RemoteLED.java | 23 - .../lejos/remote/ev3/RemoteMotorPort.java | 95 - .../java/lejos/remote/ev3/RemotePort.java | 74 - .../remote/ev3/RemoteRequestAnalogPort.java | 116 - .../lejos/remote/ev3/RemoteRequestAudio.java | 116 - .../remote/ev3/RemoteRequestBattery.java | 61 - .../lejos/remote/ev3/RemoteRequestEV3.java | 180 -- .../remote/ev3/RemoteRequestException.java | 33 - .../remote/ev3/RemoteRequestGraphicsLCD.java | 472 ---- .../remote/ev3/RemoteRequestI2CPort.java | 68 - .../lejos/remote/ev3/RemoteRequestIOPort.java | 80 - .../lejos/remote/ev3/RemoteRequestKey.java | 110 - .../lejos/remote/ev3/RemoteRequestKeys.java | 145 -- .../lejos/remote/ev3/RemoteRequestLED.java | 40 - .../lejos/remote/ev3/RemoteRequestMenu.java | 319 --- .../remote/ev3/RemoteRequestMotorPort.java | 87 - .../lejos/remote/ev3/RemoteRequestPilot.java | 290 --- .../lejos/remote/ev3/RemoteRequestPort.java | 65 - .../ev3/RemoteRequestRegulatedMotor.java | 247 -- .../ev3/RemoteRequestSampleProvider.java | 79 - .../remote/ev3/RemoteRequestTextLCD.java | 239 -- .../remote/ev3/RemoteRequestUARTPort.java | 163 -- .../java/lejos/remote/ev3/RemoteTextLCD.java | 215 -- .../java/lejos/remote/ev3/RemoteUARTPort.java | 156 -- .../java/lejos/remote/ev3/package-info.java | 6 - .../java/lejos/remote/nxt/AsciizCodec.java | 56 - .../java/lejos/remote/nxt/BTConnection.java | 96 - .../java/lejos/remote/nxt/BTConnector.java | 88 - .../java/lejos/remote/nxt/Connection.java | 7 - .../java/lejos/remote/nxt/DeviceInfo.java | 13 - .../java/lejos/remote/nxt/ErrorMessages.java | 196 -- .../main/java/lejos/remote/nxt/FileInfo.java | 27 - .../java/lejos/remote/nxt/FirmwareInfo.java | 11 - .../lejos/remote/nxt/InputConnection.java | 18 - .../java/lejos/remote/nxt/InputValues.java | 38 - .../src/main/java/lejos/remote/nxt/LCP.java | 729 ------ .../java/lejos/remote/nxt/LCPException.java | 34 - .../lejos/remote/nxt/LCPMessageListener.java | 6 - .../java/lejos/remote/nxt/LCPResponder.java | 133 - .../lejos/remote/nxt/NXJFirmwareInfo.java | 36 - .../src/main/java/lejos/remote/nxt/NXT.java | 8 - .../main/java/lejos/remote/nxt/NXTComm.java | 57 - .../lejos/remote/nxt/NXTCommConnector.java | 30 - .../java/lejos/remote/nxt/NXTCommDevice.java | 170 -- .../java/lejos/remote/nxt/NXTCommRequest.java | 30 - .../java/lejos/remote/nxt/NXTCommand.java | 995 ------- .../java/lejos/remote/nxt/NXTConnection.java | 58 - .../java/lejos/remote/nxt/NXTInputStream.java | 88 - .../lejos/remote/nxt/NXTOutputStream.java | 45 - .../java/lejos/remote/nxt/NXTProtocol.java | 170 -- .../lejos/remote/nxt/OutputConnection.java | 18 - .../java/lejos/remote/nxt/OutputState.java | 27 - .../main/java/lejos/remote/nxt/RemoteNXT.java | 163 -- .../lejos/remote/nxt/RemoteNXTAnalogPort.java | 121 - .../java/lejos/remote/nxt/RemoteNXTAudio.java | 116 - .../lejos/remote/nxt/RemoteNXTBattery.java | 52 - .../lejos/remote/nxt/RemoteNXTI2CPort.java | 149 -- .../lejos/remote/nxt/RemoteNXTIOPort.java | 126 - .../lejos/remote/nxt/RemoteNXTMotorPort.java | 96 - .../java/lejos/remote/nxt/RemoteNXTPort.java | 71 - .../lejos/remote/nxt/SocketConnection.java | 51 - .../lejos/remote/nxt/SocketConnector.java | 36 - .../lejos/remote/nxt/StreamConnection.java | 18 - .../java/lejos/remote/nxt/package-info.java | 4 - .../src/main/java/lejos/remote/rcx/LLC.java | 141 - .../java/lejos/remote/rcx/LLCHandler.java | 109 - .../lejos/remote/rcx/LLCReliableHandler.java | 103 - .../main/java/lejos/remote/rcx/Opcode.java | 129 - .../java/lejos/remote/rcx/PacketHandler.java | 86 - .../lejos/remote/rcx/RCXAbstractPort.java | 201 -- .../main/java/lejos/remote/rcx/RCXPort.java | 28 - .../lejos/remote/rcx/RCXRemoteMotorPort.java | 76 - .../main/java/lejos/remote/rcx/Serial.java | 249 -- .../java/lejos/remote/rcx/package-info.java | 4 - .../java/lejos/robotics/Accelerometer.java | 26 - .../lejos/robotics/AccelerometerAdapter.java | 34 - .../main/java/lejos/robotics/BaseMotor.java | 38 - .../main/java/lejos/robotics/Calibrate.java | 15 - .../src/main/java/lejos/robotics/Clock.java | 41 - .../src/main/java/lejos/robotics/Color.java | 74 - .../java/lejos/robotics/ColorAdapter.java | 31 - .../java/lejos/robotics/ColorDetector.java | 15 - .../java/lejos/robotics/ColorIdentifier.java | 10 - .../src/main/java/lejos/robotics/DCMotor.java | 21 - .../java/lejos/robotics/DirectionFinder.java | 25 - .../robotics/DirectionFinderAdapter.java | 39 - .../src/main/java/lejos/robotics/Encoder.java | 24 - .../java/lejos/robotics/EncoderMotor.java | 12 - .../lejos/robotics/FixedRangeScanner.java | 80 - .../main/java/lejos/robotics/Gyroscope.java | 21 - .../java/lejos/robotics/GyroscopeAdapter.java | 79 - .../java/lejos/robotics/LampController.java | 41 - .../java/lejos/robotics/LightDetector.java | 45 - .../lejos/robotics/LightDetectorAdaptor.java | 114 - .../java/lejos/robotics/LightScanner.java | 240 -- .../java/lejos/robotics/LinearActuator.java | 80 - .../main/java/lejos/robotics/MirrorMotor.java | 188 -- .../java/lejos/robotics/PressureDetector.java | 17 - .../main/java/lejos/robotics/RangeFinder.java | 23 - .../lejos/robotics/RangeFinderAdapter.java | 25 - .../java/lejos/robotics/RangeReading.java | 46 - .../java/lejos/robotics/RangeReadings.java | 121 - .../java/lejos/robotics/RangeScanner.java | 29 - .../java/lejos/robotics/RegulatedMotor.java | 174 -- .../robotics/RegulatedMotorListener.java | 21 - .../lejos/robotics/ReversedEncoderMotor.java | 46 - .../lejos/robotics/RotatingRangeScanner.java | 99 - .../java/lejos/robotics/SampleProvider.java | 56 - .../src/main/java/lejos/robotics/Servo.java | 61 - .../main/java/lejos/robotics/Tachometer.java | 19 - .../src/main/java/lejos/robotics/Touch.java | 16 - .../java/lejos/robotics/TouchAdapter.java | 19 - .../java/lejos/robotics/Transmittable.java | 11 - .../java/lejos/robotics/chassis/Chassis.java | 264 -- .../java/lejos/robotics/chassis/Wheel.java | 19 - .../robotics/chassis/WheeledChassis.java | 866 ------- .../lejos/robotics/chassis/package-info.java | 4 - .../filter/AbstractCalibrationFilter.java | 209 -- .../lejos/robotics/filter/AbstractFilter.java | 28 - .../lejos/robotics/filter/AzimuthFilter.java | 89 - .../robotics/filter/ConcatenationFilter.java | 28 - .../main/java/lejos/robotics/filter/Dump.java | 34 - .../lejos/robotics/filter/FilterTerminal.java | 38 - .../robotics/filter/IntegrationFilter.java | 57 - .../filter/LinearCalibrationFilter.java | 306 --- .../lejos/robotics/filter/LowPassFilter.java | 60 - .../lejos/robotics/filter/MaximumFilter.java | 44 - .../lejos/robotics/filter/MeanFilter.java | 25 - .../lejos/robotics/filter/MedianFilter.java | 45 - .../lejos/robotics/filter/MinimumFilter.java | 42 - .../lejos/robotics/filter/ModulusFilter.java | 28 - .../filter/OffsetCorrectionFilter.java | 190 -- .../lejos/robotics/filter/PublishFilter.java | 150 -- .../robotics/filter/PublishedSource.java | 161 -- .../lejos/robotics/filter/SampleBuffer.java | 64 - .../lejos/robotics/filter/SampleThread.java | 101 - .../lejos/robotics/filter/SliceFilter.java | 33 - .../robotics/filter/SubscribedProvider.java | 86 - .../java/lejos/robotics/filter/SumFilter.java | 127 - .../lejos/robotics/filter/ZeroFilter.java | 26 - .../lejos/robotics/filter/package-info.java | 4 - .../java/lejos/robotics/geometry/Line.java | 133 - .../java/lejos/robotics/geometry/Line2D.java | 583 ----- .../java/lejos/robotics/geometry/Point.java | 287 -- .../java/lejos/robotics/geometry/Point2D.java | 260 -- .../lejos/robotics/geometry/Rectangle.java | 9 - .../lejos/robotics/geometry/Rectangle2D.java | 406 --- .../robotics/geometry/RectangleInt32.java | 337 --- .../robotics/geometry/RectangularShape.java | 184 -- .../java/lejos/robotics/geometry/Shape.java | 81 - .../lejos/robotics/geometry/package-info.java | 4 - .../robotics/localization/BeaconLocator.java | 21 - .../localization/BeaconPoseProvider.java | 334 --- .../robotics/localization/BeaconTriangle.java | 109 - .../localization/CompassPoseProvider.java | 30 - .../robotics/localization/MCLParticle.java | 138 - .../robotics/localization/MCLParticleSet.java | 437 ---- .../localization/MCLPoseProvider.java | 567 ---- .../localization/OdometryPoseProvider.java | 148 -- .../robotics/localization/PoseProvider.java | 15 - .../robotics/localization/package-info.java | 4 - .../robotics/mapping/EV3NavigationModel.java | 620 ----- .../java/lejos/robotics/mapping/LineMap.java | 179 -- .../robotics/mapping/NavEventListener.java | 9 - .../robotics/mapping/NavigationModel.java | 172 -- .../robotics/mapping/OccupancyGridMap.java | 57 - .../java/lejos/robotics/mapping/RangeMap.java | 39 - .../lejos/robotics/mapping/SVGMapLoader.java | 61 - .../robotics/mapping/ShapefileLoader.java | 229 -- .../lejos/robotics/mapping/package-info.java | 4 - .../robotics/navigation/ArcAlgorithms.java | 468 ---- .../navigation/ArcMoveController.java | 161 -- .../navigation/ArcRotateMoveController.java | 8 - .../lejos/robotics/navigation/Ballbot.java | 484 ---- .../robotics/navigation/CompassPilot.java | 311 --- .../DestinationUnreachableException.java | 11 - .../navigation/DifferentialPilot.java | 1238 --------- .../LineFollowingMoveController.java | 78 - .../java/lejos/robotics/navigation/Move.java | 285 -- .../robotics/navigation/MoveController.java | 95 - .../robotics/navigation/MoveListener.java | 37 - .../lejos/robotics/navigation/MovePilot.java | 426 --- .../robotics/navigation/MoveProvider.java | 26 - .../navigation/NavigationListener.java | 36 - .../lejos/robotics/navigation/Navigator.java | 461 ---- .../lejos/robotics/navigation/OmniPilot.java | 842 ------ .../java/lejos/robotics/navigation/Pose.java | 225 -- .../navigation/RotateMoveController.java | 54 - .../robotics/navigation/SteeringPilot.java | 358 --- .../lejos/robotics/navigation/Waypoint.java | 108 - .../robotics/navigation/WaypointListener.java | 20 - .../robotics/navigation/package-info.java | 4 - .../robotics/objectdetection/Feature.java | 39 - .../objectdetection/FeatureDetector.java | 85 - .../FeatureDetectorAdapter.java | 89 - .../objectdetection/FeatureListener.java | 18 - .../objectdetection/FusorDetector.java | 187 -- .../objectdetection/RangeFeature.java | 109 - .../objectdetection/RangeFeatureDetector.java | 110 - .../objectdetection/TouchFeatureDetector.java | 76 - .../objectdetection/package-info.java | 4 - .../java/lejos/robotics/package-info.java | 4 - .../pathfinding/AstarSearchAlgorithm.java | 135 - .../pathfinding/DijkstraPathFinder.java | 446 ---- .../robotics/pathfinding/FourWayGridMesh.java | 209 -- .../lejos/robotics/pathfinding/GridNode.java | 23 - .../robotics/pathfinding/NavigationMesh.java | 65 - .../java/lejos/robotics/pathfinding/Node.java | 175 -- .../robotics/pathfinding/NodePathFinder.java | 107 - .../java/lejos/robotics/pathfinding/Path.java | 34 - .../robotics/pathfinding/PathFinder.java | 20 - .../pathfinding/RandomPathFinder.java | 190 -- .../pathfinding/RandomSelfGeneratingNode.java | 112 - .../robotics/pathfinding/SearchAlgorithm.java | 21 - .../pathfinding/ShortestPathFinder.java | 551 ---- .../robotics/pathfinding/package-info.java | 4 - .../robotics/subsumption/Arbitrator.java | 151 -- .../lejos/robotics/subsumption/Behavior.java | 55 - .../robotics/subsumption/package-info.java | 4 - .../java/lejos/utility/DebugMessages.java | 128 - .../src/main/java/lejos/utility/Delay.java | 71 - .../main/java/lejos/utility/EndianTools.java | 100 - .../lejos/utility/GyroDirectionFinder.java | 159 -- .../main/java/lejos/utility/Integration.java | 46 - .../main/java/lejos/utility/KalmanFilter.java | 63 - .../java/lejos/utility/LUDecomposition.java | 313 --- .../src/main/java/lejos/utility/Matrix.java | 817 ------ .../main/java/lejos/utility/PilotProps.java | 75 - .../java/lejos/utility/SensorSelector.java | 48 - .../utility/SensorSelectorException.java | 9 - .../main/java/lejos/utility/Stopwatch.java | 30 - .../src/main/java/lejos/utility/TextMenu.java | 278 -- .../src/main/java/lejos/utility/Timer.java | 82 - .../java/lejos/utility/TimerListener.java | 17 - .../main/java/lejos/utility/package-info.java | 4 - gradle.properties | 3 + samples/build.gradle | 81 +- samples/build.gradle.bck | 42 + .../mindstorms/samples/HelloWorld.java} | 9 +- settings.gradle | 2 - 500 files changed, 131 insertions(+), 68387 deletions(-) delete mode 100644 dbusjava/build.gradle delete mode 100644 dbusjava/src/main/java/lejos/internal/io/NativeDomainSocket.java delete mode 100644 dbusjava/src/main/java/lejos/internal/io/SocketInputStream.java delete mode 100644 dbusjava/src/main/java/lejos/internal/io/SocketOutputStream.java delete mode 100644 dbusjava/src/main/java/lejos/internal/io/package-info.java delete mode 100644 ev3classes/build.gradle delete mode 100644 ev3classes/src/main/java/lejos/hardware/Audio.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Battery.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Bluetooth.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/BluetoothException.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Brick.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/BrickFinder.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/BrickInfo.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Button.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Device.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/DeviceException.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Key.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/KeyListener.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Keys.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/LED.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/ListenerCaller.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/LocalBTDevice.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/LocalWifiDevice.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Power.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/RemoteBTDevice.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Sound.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Sounds.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/Wifi.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/DLight.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/DLights.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/DeviceIdentifier.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/IRLink.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/IRTransmitter.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/LDCMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/LMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/LSC.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/LServo.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/LnrActrFirgelliNXT.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/MMXMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/MMXRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/MSC.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/MServo.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/MindSensorsNumPad.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/NXTCam.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/NXTMMX.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/NXTe.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/PFLink.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/PFMate.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/PFMateMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/PFMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/PSPNXController.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/RCXLink.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/RCXMotorMultiplexer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/RCXPlexedMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/RCXSensorMultiplexer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/SensorMux.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/TouchMUX.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/UART.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixControllerFactory.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixEncoderMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotorController.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServo.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServoController.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/device/tetrix/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/ev3/EV3.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/ev3/LocalEV3.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/ev3/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/Coordinates.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/GGASentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/GPS.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/GPSListener.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/GSASentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/GSVSentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/NMEASentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/RMCSentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/Satellite.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/SimpleGPS.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/VTGSentence.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/gps/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/CommonLCD.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/Font.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/GraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/Image.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/LCD.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/LCDOutputStream.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/TextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/lcd/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/BaseRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/BasicMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/EV3LargeRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/EV3MediumRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/JavaMotorRegulator.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelMRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelXLRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/Motor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/MotorRegulator.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/NXTRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/RCXMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/Tachometer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/UnregulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/motor/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/AnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/BasicMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/BasicSensorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/ConfigurationPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/I2CException.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/I2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/IOPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/LegacySensorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/MotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/Port.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/PortException.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/SensorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/TachoMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/UARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/port/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/AnalogSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/BaseSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/CodeTemplate.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/CruizcoreGyro.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterCompassSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterGPSSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterIMUSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterLaserSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor250.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor500.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/DexterThermalIRSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3ColorSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3GyroSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3IRSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3SensorConstants.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3TouchSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/EV3UltrasonicSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAccelerometer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAngleSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicBarometer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicColorSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicCompass.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicEOPD.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicGyro.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeeker.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeekerV2.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicMagneticSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/I2CSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindSensorsPressureSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAbsoluteIMU.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAccelerometer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsBTSense.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsCompass.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsDistanceSensorV2.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsLightSensorArray.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsLineLeader.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/NXTColorSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/NXTLightSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/NXTSoundSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/NXTTouchSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/NXTUltrasonicSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/RCXLightSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/RCXRotationSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/RCXThermometer.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/RFIDSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/SensorConstants.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/SensorMode.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/SensorModes.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/SumoEyesSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/UARTSensor.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/sensor/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/video/Video.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/video/VideoUtils.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/video/YUYVImage.java delete mode 100644 ev3classes/src/main/java/lejos/hardware/video/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/Adapter.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/Agent.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/DBusBluez.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/DBusProperties.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/Device.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/Manager.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/PinAgent.java delete mode 100644 ev3classes/src/main/java/lejos/internal/dbus/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3AnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Audio.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Battery.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3ConfigurationPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3GraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3I2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3IOPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Key.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Keys.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3LCD.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3LCDManager.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3LED.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3MotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Port.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3TextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3UARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Video.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/EV3Wrapper.java delete mode 100644 ev3classes/src/main/java/lejos/internal/ev3/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/NativeDevice.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/NativeFile.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/NativeHCI.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/NativeSocket.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/NativeWifi.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/Settings.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/SystemSettings.java delete mode 100644 ev3classes/src/main/java/lejos/internal/io/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/EV3Reply.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/EV3Request.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/Menu.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/MenuReply.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/MenuRequest.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIAnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIAudio.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIBattery.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIBluetooth.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIEV3.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIGraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMII2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIKey.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIKeys.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMILCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMILED.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIMenu.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAudio.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBattery.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBluetooth.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteEV3.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteGraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteI2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKey.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKeys.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLED.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteSampleProvider.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteTextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteUARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteWifi.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMISampleProvider.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMITextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIUARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RMIWifi.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteAnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteAudio.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteBattery.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteEV3.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteGraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteI2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteIOPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteKey.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteKeys.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteLED.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemotePort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestAnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestAudio.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestBattery.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestEV3.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestException.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestGraphicsLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestI2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestIOPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestKey.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestKeys.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestLED.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestMenu.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestPilot.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestRegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestSampleProvider.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestTextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestUARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteTextLCD.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/RemoteUARTPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/ev3/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/AsciizCodec.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/BTConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/BTConnector.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/Connection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/DeviceInfo.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/ErrorMessages.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/FileInfo.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/FirmwareInfo.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/InputConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/InputValues.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/LCP.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/LCPException.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/LCPMessageListener.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/LCPResponder.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXJFirmwareInfo.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXT.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTComm.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTCommConnector.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTCommDevice.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTCommRequest.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTCommand.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTInputStream.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTOutputStream.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/NXTProtocol.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/OutputConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/OutputState.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXT.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAnalogPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAudio.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTBattery.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTI2CPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTIOPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/SocketConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/SocketConnector.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/StreamConnection.java delete mode 100644 ev3classes/src/main/java/lejos/remote/nxt/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/LLC.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/LLCHandler.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/LLCReliableHandler.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/Opcode.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/PacketHandler.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/RCXAbstractPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/RCXPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/RCXRemoteMotorPort.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/Serial.java delete mode 100644 ev3classes/src/main/java/lejos/remote/rcx/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Accelerometer.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/AccelerometerAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/BaseMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Calibrate.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Clock.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Color.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/ColorAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/ColorDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/ColorIdentifier.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/DCMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/DirectionFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/DirectionFinderAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Encoder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/EncoderMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/FixedRangeScanner.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Gyroscope.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/GyroscopeAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/LampController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/LightDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/LightDetectorAdaptor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/LightScanner.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/LinearActuator.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/MirrorMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/PressureDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RangeFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RangeFinderAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RangeReading.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RangeReadings.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RangeScanner.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RegulatedMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RegulatedMotorListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/ReversedEncoderMotor.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/RotatingRangeScanner.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/SampleProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Servo.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Tachometer.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Touch.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/TouchAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/Transmittable.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/chassis/Chassis.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/chassis/Wheel.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/chassis/WheeledChassis.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/chassis/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/AbstractCalibrationFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/AbstractFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/AzimuthFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/ConcatenationFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/Dump.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/FilterTerminal.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/IntegrationFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/LinearCalibrationFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/LowPassFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/MaximumFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/MeanFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/MedianFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/MinimumFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/ModulusFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/OffsetCorrectionFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/PublishFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/PublishedSource.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/SampleBuffer.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/SampleThread.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/SliceFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/SubscribedProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/SumFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/ZeroFilter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/filter/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Line.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Line2D.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Point.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Point2D.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Rectangle.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Rectangle2D.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/RectangleInt32.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/RectangularShape.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/Shape.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/geometry/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/BeaconLocator.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/BeaconPoseProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/BeaconTriangle.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/CompassPoseProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/MCLParticle.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/MCLParticleSet.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/MCLPoseProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/OdometryPoseProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/PoseProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/localization/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/EV3NavigationModel.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/LineMap.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/NavEventListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/NavigationModel.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/OccupancyGridMap.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/RangeMap.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/SVGMapLoader.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/ShapefileLoader.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/mapping/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/ArcAlgorithms.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/ArcMoveController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/ArcRotateMoveController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/Ballbot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/CompassPilot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/DestinationUnreachableException.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/DifferentialPilot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/LineFollowingMoveController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/Move.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/MoveController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/MoveListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/MovePilot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/MoveProvider.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/NavigationListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/Navigator.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/OmniPilot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/Pose.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/RotateMoveController.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/SteeringPilot.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/Waypoint.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/WaypointListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/navigation/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/Feature.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetectorAdapter.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureListener.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/FusorDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeature.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeatureDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/TouchFeatureDetector.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/objectdetection/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/AstarSearchAlgorithm.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/DijkstraPathFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/FourWayGridMesh.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/GridNode.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/NavigationMesh.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/Node.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/NodePathFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/Path.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/PathFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/RandomPathFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/RandomSelfGeneratingNode.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/SearchAlgorithm.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/ShortestPathFinder.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/pathfinding/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/subsumption/Arbitrator.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/subsumption/Behavior.java delete mode 100644 ev3classes/src/main/java/lejos/robotics/subsumption/package-info.java delete mode 100644 ev3classes/src/main/java/lejos/utility/DebugMessages.java delete mode 100644 ev3classes/src/main/java/lejos/utility/Delay.java delete mode 100644 ev3classes/src/main/java/lejos/utility/EndianTools.java delete mode 100644 ev3classes/src/main/java/lejos/utility/GyroDirectionFinder.java delete mode 100644 ev3classes/src/main/java/lejos/utility/Integration.java delete mode 100644 ev3classes/src/main/java/lejos/utility/KalmanFilter.java delete mode 100644 ev3classes/src/main/java/lejos/utility/LUDecomposition.java delete mode 100644 ev3classes/src/main/java/lejos/utility/Matrix.java delete mode 100644 ev3classes/src/main/java/lejos/utility/PilotProps.java delete mode 100644 ev3classes/src/main/java/lejos/utility/SensorSelector.java delete mode 100644 ev3classes/src/main/java/lejos/utility/SensorSelectorException.java delete mode 100644 ev3classes/src/main/java/lejos/utility/Stopwatch.java delete mode 100644 ev3classes/src/main/java/lejos/utility/TextMenu.java delete mode 100644 ev3classes/src/main/java/lejos/utility/Timer.java delete mode 100644 ev3classes/src/main/java/lejos/utility/TimerListener.java delete mode 100644 ev3classes/src/main/java/lejos/utility/package-info.java create mode 100644 samples/build.gradle.bck rename samples/src/main/java/{Main.java => com/github/bdeneuter/mindstorms/samples/HelloWorld.java} (63%) diff --git a/build.gradle b/build.gradle index b82210f..8b13789 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1 @@ -plugins { - id "nebula.provided-base" version "2.2.0" -} -subprojects { - apply plugin: "nebula.provided-base" - apply plugin: 'java' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - - repositories { - mavenCentral() - } - - -} diff --git a/dbusjava/build.gradle b/dbusjava/build.gradle deleted file mode 100644 index c0352c3..0000000 --- a/dbusjava/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compile 'com.github.bdeneuter:dbus-java:2.7' - compile 'net.java.dev.jna:jna:3.2.7' -} diff --git a/dbusjava/src/main/java/lejos/internal/io/NativeDomainSocket.java b/dbusjava/src/main/java/lejos/internal/io/NativeDomainSocket.java deleted file mode 100644 index 7485cd3..0000000 --- a/dbusjava/src/main/java/lejos/internal/io/NativeDomainSocket.java +++ /dev/null @@ -1,197 +0,0 @@ -package lejos.internal.io; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.Buffer; -import java.nio.ByteBuffer; - -import com.sun.jna.LastErrorException; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.ptr.IntByReference; - -public class NativeDomainSocket { - - public static final int AF_UNIX = 1; - public static final int SOCK_STREAM = 1; - - public static final int SOL_SOCKET = 65535; - - private SocketInputStream is; - private SocketOutputStream os; - - public static class SockAddr extends Structure implements Structure.ByReference { - public short family = AF_UNIX; - public byte[] addr = new byte[108]; - - public SockAddr() { - //System.out.println("Socket address created"); - } - - public SockAddr(String name, boolean abs) { - //System.out.println("Socket address created with address = " + addr + ", abstract = " + abs); - System.arraycopy(name.getBytes(), 0, addr, 0, name.length()); - //System.out.println("Array copied"); - } - } - - public SockAddr sa = new SockAddr(); - - static class Linux_C_lib_DirectMapping { - native public int fcntl(int fd, int cmd, int arg) throws LastErrorException; - - native public int ioctl(int fd, int cmd, byte[] arg) throws LastErrorException; - - native public int ioctl(int fd, int cmd, Pointer p) throws LastErrorException; - - native public int open(String path, int flags) throws LastErrorException; - - native public int close(int fd) throws LastErrorException; - - native public int write(int fd, Buffer buffer, int count) throws LastErrorException; - - native public int read(int fd, Buffer buffer, int count) throws LastErrorException; - - native public int socket(int domain, int type, int protocol) throws LastErrorException; - - native public int connect(int sockfd, SockAddr sockaddr, int addrlen) throws LastErrorException; - - native public int bind(int sockfd, SockAddr sockaddr, int addrlen) throws LastErrorException; - - native public int accept(int sockfd, SockAddr rem_addr, Pointer opt) throws LastErrorException; - - native public int listen(int sockfd, int channel) throws LastErrorException; - - native public int getsockopt(int s, int level, int optname, byte[] optval, IntByReference optlen); - - native public int setsockopt(int s, int level, int optname, byte[] optval, int optlen); - - native public int recv(int s, Buffer buf, int len, int flags) throws LastErrorException; - native public int recvfrom(int s, Buffer buf, int len, int flags, SockAddr from, IntByReference fromlen); - - native public int send(int s, Buffer msg, int len, int flags) throws LastErrorException; - - static { - try { - Native.register("c"); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - static Linux_C_lib_DirectMapping clib = new Linux_C_lib_DirectMapping(); - int socket; - - - public NativeDomainSocket() throws LastErrorException { - //System.out.println("Domain Socket created"); - socket = clib.socket(AF_UNIX, SOCK_STREAM, 0); - //System.out.println("Socket is " + socket); - } - - public NativeDomainSocket(SockAddr addr, boolean ab) throws LastErrorException { - //System.out.println("Domain Socket created , abstract = " + false); - socket = clib.socket(AF_UNIX, SOCK_STREAM, 0); - //System.out.println("Socket is " + socket); - } - - public NativeDomainSocket(SockAddr addr) throws LastErrorException { - this(addr,false); - } - - public void connect(SockAddr addr) throws LastErrorException { - //System.out.println("Connect called with address " + addr); - clib.connect(socket, addr, addr.size()); - is = new SocketInputStream(this); - os = new SocketOutputStream(this); - } - - /** - * Attempt to read the requested number of bytes from the associated file. - * @param buf location to store the read bytes - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int read(byte[] buf, int len) throws LastErrorException { - return clib.read(socket,ByteBuffer.wrap(buf, 0, len), len); - } - - /** - * Attempt to write the requested number of bytes to the associated file. - * @param buf location to store the read bytes - * @param offset the offset within buf to take data from for the write - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int write(byte[] buf, int offset, int len) throws LastErrorException { - return clib.write(socket, ByteBuffer.wrap(buf, offset, len), len); - } - - public int send(byte[] buf, int len) { - return clib.send(socket,ByteBuffer.wrap(buf, 0, len), len, 0); - } - - public int recv(byte[] buf, int len) throws LastErrorException { - return clib.recv(socket,ByteBuffer.wrap(buf, 0, len), len, 0); - } - - public void close() throws LastErrorException { - clib.close(socket); - } - - public NativeDomainSocket accept() { - return this; - } - - public void bind(SockAddr sockaddr) throws LastErrorException { - clib.bind(socket, sockaddr, sockaddr.size()); - } - - public void sendCredentialByte(byte data) throws IOException - { - //System.out.println("Send Credential byte " + data); - byte[] b = new byte[1]; - send(b,1); - - } - - public byte recvCredentialByte() throws IOException - { - System.out.println("Read credential byte"); - return 0; - } - - public int getPeerUID() - { - //System.out.println("Get Peer UID"); - return 0; - } - - public void setPassCred(boolean enable) throws IOException - { - //System.out.println("set Pass Cred, enable = " + enable); - } - - public void setBlocking(boolean enable) - { - //System.out.println("Set Blocking"); - } - - public void setSoTimeout(int timeout) - { - //System.out.println("Set timeout " + timeout); - } - - public InputStream getInputStream() - { - return is; - } - - public OutputStream getOutputStream() - { - return os; - } -} diff --git a/dbusjava/src/main/java/lejos/internal/io/SocketInputStream.java b/dbusjava/src/main/java/lejos/internal/io/SocketInputStream.java deleted file mode 100644 index a9fa022..0000000 --- a/dbusjava/src/main/java/lejos/internal/io/SocketInputStream.java +++ /dev/null @@ -1,37 +0,0 @@ -package lejos.internal.io; - -import java.io.IOException; -import java.io.InputStream; - -public class SocketInputStream extends InputStream { - private NativeDomainSocket sock; - private byte[] buf = new byte[1]; - - public SocketInputStream(NativeDomainSocket sock) { - this.sock = sock; - } - - @Override - public int read() throws IOException { - int count = sock.recv(buf, 1); - //System.out.println("Read" + count + " " + buf[0] + " " + ((char) buf[0])); - return buf[0] & 0xFF; - } - - public int read(byte[] b, int off, int len) throws IOException - { - int count = sock.recv(b, len); - /* Yes, I really want to do this. Recv returns 0 for 'connection shut down'. - * read() returns -1 for 'end of stream. - * Recv returns -1 for 'EAGAIN' (all other errors cause an exception to be raised) - * whereas read() returns 0 for '0 bytes read', so yes, I really want to swap them here. - */ - if (0 == count) return -1; - else if (-1 == count) return 0; - else { - //System.out.println("Received " + count + " " + b[0] + ((char) b[0])); - return count; - } - } - -} diff --git a/dbusjava/src/main/java/lejos/internal/io/SocketOutputStream.java b/dbusjava/src/main/java/lejos/internal/io/SocketOutputStream.java deleted file mode 100644 index d84fd20..0000000 --- a/dbusjava/src/main/java/lejos/internal/io/SocketOutputStream.java +++ /dev/null @@ -1,26 +0,0 @@ -package lejos.internal.io; - -import java.io.IOException; -import java.io.OutputStream; - -public class SocketOutputStream extends OutputStream { - NativeDomainSocket sock; - - public SocketOutputStream(NativeDomainSocket sock) { - this.sock = sock; - } - @Override - public void write(int b) throws IOException { - System.out.println("Not Writing " + b + ((char) b)); - } - - public void write(byte[] b, int off, int len) throws IOException - { - //System.out.println("Writing len = " + len + " " + b[0]); - sock.send(b, len); - } - - public void write(byte [][] b) throws IOException { - System.err.println("Not implemented"); - } -} diff --git a/dbusjava/src/main/java/lejos/internal/io/package-info.java b/dbusjava/src/main/java/lejos/internal/io/package-info.java deleted file mode 100644 index 6358d56..0000000 --- a/dbusjava/src/main/java/lejos/internal/io/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * - */ -/** - * @author Lawrie Griiffiths - * - */ -package lejos.internal.io; \ No newline at end of file diff --git a/ev3classes/build.gradle b/ev3classes/build.gradle deleted file mode 100644 index 45db92e..0000000 --- a/ev3classes/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compile 'com.github.bdeneuter:dbus-java:2.7' - compile 'net.java.dev.jna:jna:3.2.7' -} diff --git a/ev3classes/src/main/java/lejos/hardware/Audio.java b/ev3classes/src/main/java/lejos/hardware/Audio.java deleted file mode 100644 index 0837f60..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Audio.java +++ /dev/null @@ -1,96 +0,0 @@ -package lejos.hardware; - -import java.io.File; - - - -public interface Audio extends Sounds -{ - /** - * Play a system sound. - * - * - * - * - * - * - * - *
aCodeResulting Sound
0short beep
1double beep
2descending arpeggio
3ascending arpeggio
4long, low buzz
- */ - public void systemSound(int aCode); - - /** - * Plays a tone, given its frequency and duration. - * @param aFrequency The frequency of the tone in Hertz (Hz). - * @param aDuration The duration of the tone, in milliseconds. - * @param aVolume The volume of the playback 100 corresponds to 100% - */ - public void playTone(int aFrequency, int aDuration, int aVolume); - - - public void playTone(int freq, int duration); - - - /** - * Play a wav file - * @param file the 8-bit PWM (WAV) sample file - * @param vol the volume percentage 0 - 100 - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file, int vol); - - - /** - * Play a wav file - * @param file the 8-bit PWM (WAV) sample file - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file); - - /** - * Queue a series of PCM samples to play at the - * specified volume and sample rate. - * - * @param data Buffer containing the samples - * @param offset Offset of the first sample in the buffer - * @param len Number of samples to queue - * @param freq Sample rate - * @param vol playback volume - * @return Number of samples actually queued - */ - public int playSample(byte [] data, int offset, int len, int freq, int vol); - - /** - * Play a note with attack, decay, sustain and release shape. This function - * allows the playing of a more musical sounding note. It uses a set of - * supplied "instrument" parameters to define the shape of the notes - * envelope. - * @param inst Instrument definition - * @param freq The note to play (in Hz) - * @param len The duration of the note (in ms) - */ - public void playNote(int[] inst, int freq, int len); - - /** - * Set the master volume level - * @param vol 0-100 - */ - public void setVolume(int vol); - - /** - * Get the current master volume level - * @return the current master volume 0-100 - */ - public int getVolume(); - - /** - * Load the current system settings associated with this class. Called - * automatically to initialize the class. May be called if it is required - * to reload any settings. - */ - public void loadSettings(); -} diff --git a/ev3classes/src/main/java/lejos/hardware/Battery.java b/ev3classes/src/main/java/lejos/hardware/Battery.java deleted file mode 100644 index c670367..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Battery.java +++ /dev/null @@ -1,21 +0,0 @@ -package lejos.hardware; - -public class Battery { - private static Power power = BrickFinder.getDefault().getPower(); - - public static int getVoltageMilliVolt() { - return power.getVoltageMilliVolt(); - } - - public static float getVoltage() { - return power.getVoltage(); - } - - public static float getBatteryCurrent() { - return power.getBatteryCurrent(); - } - - public static float getMotorCurrent() { - return power.getMotorCurrent(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Bluetooth.java b/ev3classes/src/main/java/lejos/hardware/Bluetooth.java deleted file mode 100644 index 9d736ef..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Bluetooth.java +++ /dev/null @@ -1,53 +0,0 @@ -package lejos.hardware; - -import lejos.remote.nxt.BTConnector; -import lejos.remote.nxt.NXTCommConnector; - -public class Bluetooth { - public static NXTCommConnector getNXTCommConnector() { - return new BTConnector(); - } - - public static LocalBTDevice getLocalDevice() { - return new LocalBTDevice(); - } - - // Utility methods - - - /** - * Return a Bluetooth binary address given a String version of the address - * @param address String address - * @return Binary address - */ - public static byte[] getAddress(String address) { - byte[] bdaddr = new byte[6]; - - for(int i=0;i=0;j--) { - String hex = Integer.toHexString(address[j] & 0xFF).toUpperCase(); - if (hex.length() == 1) sb.append('0'); - sb.append(hex); - if (j>0) sb.append(':'); - } - return sb.toString(); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/BluetoothException.java b/ev3classes/src/main/java/lejos/hardware/BluetoothException.java deleted file mode 100644 index 5ccbd7c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/BluetoothException.java +++ /dev/null @@ -1,29 +0,0 @@ -package lejos.hardware; - -/** - * Exception thrown when errors are detected in the Bluetooth classes. - * @author andy - * - */ -public class BluetoothException extends RuntimeException -{ - - public BluetoothException() - { - } - - public BluetoothException(String message) - { - super (message); - } - - public BluetoothException(Throwable cause) - { - super (cause); - } - - public BluetoothException(String message, Throwable cause) - { - super (message, cause); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Brick.java b/ev3classes/src/main/java/lejos/hardware/Brick.java deleted file mode 100644 index 6939b02..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Brick.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.hardware; - -import lejos.hardware.Audio; -import lejos.hardware.Power; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.TextLCD; -import lejos.hardware.port.Port; -import lejos.hardware.video.Video; - -public interface Brick -{ - /** - * Return a port object for the request port name. This allows access to the - * hardware associated with the specified port. - * @param portName The name of port - * @return the request port - */ - public Port getPort(String portName); - - /** - * return a battery object which can be used to obtain battery voltage etc. - * @return A battery object - */ - public Power getPower(); - - /** - * return a Audio object which can be used to access the device's audio playback - * @return A Audio device - */ - public Audio getAudio(); - - public Video getVideo(); - /** - * Get text access to the LCD using the default font - * @return the text LCD - */ - public TextLCD getTextLCD(); - - /** - * Get text access to the LCD using a specified font - * @param f the font - * @return the text LCD - */ - public TextLCD getTextLCD(Font f); - - /** - * Get graphics access to the LCD - * @return the graphics LCD - */ - public GraphicsLCD getGraphicsLCD(); - - /** - * Test whether the brick is a local one - * @return true iff brick is local - */ - public boolean isLocal(); - - /** - * Get the type of brick, e.g. "EV3", "NXT", "BrickPi" - * @return the brick type - */ - public String getType(); - - /** - * Get he name of the brick - * @return the name - */ - public String getName(); - - /** - * Get the local Bluetooth device - * @return the local Bluetooth device - */ - public LocalBTDevice getBluetoothDevice(); - - /** - * Get the local Wifi device - * @return the local Wifi device - */ - public LocalWifiDevice getWifiDevice(); - - /** - * Set this brick as the default one for static methods - */ - public void setDefault(); - - /** - * Get access to the keys (buttons) - * @return an implementation of the Keys interface - */ - public Keys getKeys(); - - /** - * Get access to a specific Key (aka Button) - * @param name the key name - * @return an implementation of the Key interface - */ - public Key getKey(String name); - - /** - * Get access to the LED - * @return an implementation of the LED interface - */ - public LED getLED(); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/BrickFinder.java b/ev3classes/src/main/java/lejos/hardware/BrickFinder.java deleted file mode 100644 index ce34d2d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/BrickFinder.java +++ /dev/null @@ -1,331 +0,0 @@ -package lejos.hardware; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InterfaceAddress; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.SocketTimeoutException; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; - -import lejos.hardware.ev3.LocalEV3; -import lejos.remote.ev3.RemoteEV3; - -public class BrickFinder { - private static final int DISCOVERY_PORT = 3016; - private static final String FIND_CMD = "find"; - private static Brick defaultBrick, localBrick; - private static final int MAX_DISCOVERY_TIME = 2000; - private static final int MAX_PACKET_SIZE = 32; - private static final int MAX_HOPS = 2; - - /** - * Internal class to implement a name server that can respond to queries - * generated by discover and find methods. User code will not normally need to - * run an instance of this as the leJOS menu will usually do so. - * @author andy - * - */ - private static class DiscoveryServer implements Runnable - { - DatagramSocket socket; - boolean forward; - static DiscoveryServer server; - static Thread serverThread; - - private DiscoveryServer(boolean forward) - { - this.forward = forward; - } - - public void run() - { - try { - // Keep a socket open to listen to all the UDP trafic that is - // destined for this port - socket = new DatagramSocket(DISCOVERY_PORT, - InetAddress.getByName("0.0.0.0")); - socket.setBroadcast(true); - // make sure localBrick is valid - if (getLocal() == null) return; - // Receive a packet - byte[] recvBuf = new byte[MAX_PACKET_SIZE]; - DatagramPacket packet = new DatagramPacket(recvBuf, - recvBuf.length); - while (true) - { - // Receive a packet - socket.receive(packet); - // Packet received - //System.out.println(getClass().getName() - //+ ">>>Discovery packet received from: " - //+ packet.getAddress().getHostAddress()); - // See if the packet holds the right command (message) - String message = new String(packet.getData(), 0, packet.getLength()).trim(); - //System.out.println("Message " + message); - String[] args = message.split("\\s+"); - if (args.length == 5 && args[0].equalsIgnoreCase(FIND_CMD)) - { - InetAddress replyAddr = InetAddress.getByName(args[2]); - int replyPort = Integer.parseInt(args[3]); - int hops = Integer.parseInt(args[4]); - String hostname = localBrick.getName(); - if ((!forward || hops == MAX_HOPS) && (args[1].equalsIgnoreCase("*") || args[1].equalsIgnoreCase(hostname))) - { - byte[] sendData = hostname.getBytes(); - //System.out.println("Send response to " + replyAddr); - // Send a response - DatagramPacket sendPacket = new DatagramPacket( - sendData, sendData.length, replyAddr, - replyPort); - try { - socket.send(sendPacket); - } catch (IOException e) - { - System.out.println("Error in send" + e); - // ignore errors on send , we need to keep running - } - - //System.out.println(getClass().getName() - //+ ">>>Sent packet to: " - //+ sendPacket.getAddress().getHostAddress()); - } - if (forward && --hops > 0) - broadcastFindRequest(socket, args[1], replyAddr, replyPort, hops); - } - } - } catch (SocketException e) { - // do nothing we use this to force an exit of the thread - } catch (IOException e) { - System.out.println("Brickfinder Got error " + e); - } finally { - socket.close(); - } - } - - /** - * Start the discovery server for this device - * @param forward true if requests should be forwarded to other devices - */ - public static synchronized void start(boolean forward) - { - if (server == null) - { - server = new DiscoveryServer(forward); - serverThread = new Thread(server); - serverThread.setDaemon(true); - serverThread.start(); - } - } - - /** - * Stop the discovery service on this device. Wait for the server to exit. - */ - public static synchronized void stop() - { - if (server != null && server.socket != null) - { - // abort the running server - if (server.socket != null) - server.socket.close(); - try - { - serverThread.join(); - } catch (InterruptedException e) - { - // not a lot to do - } - server.socket = null; - server = null; - } - } - } - - - public static Brick getLocal() { - if (localBrick != null) return localBrick; - // Check we are running on an EV3 - localBrick = LocalEV3.get(); - return localBrick; - } - - public static Brick getDefault() { - if (defaultBrick != null) return defaultBrick; - try { - // See if we are running on an EV3 - defaultBrick = LocalEV3.get(); - return defaultBrick; - } catch (Throwable e) { - try { - BrickInfo[] bricks = discover(); - if (bricks.length > 0) { - defaultBrick = new RemoteEV3(bricks[0].getIPAddress()); - return defaultBrick; - } else throw new DeviceException("No EV3 brick found"); - } catch (Exception e1) { - throw new DeviceException("No brick found"); - } - } - } - - private static void broadcastFindRequest(DatagramSocket socket, String name, InetAddress replyAddr, int replyPort, int hop) - { - try - { - // Broadcast the message over all the network interfaces - Enumeration interfaces = NetworkInterface - .getNetworkInterfaces(); - while (interfaces.hasMoreElements()) - { - NetworkInterface networkInterface = (NetworkInterface) interfaces - .nextElement(); - - if (networkInterface.isLoopback() || !networkInterface.isUp()) - { - continue; // Don't want to broadcast to the loopback - // interface - } - - for (InterfaceAddress interfaceAddress : networkInterface - .getInterfaceAddresses()) - { - InetAddress broadcast = interfaceAddress.getBroadcast(); - if (broadcast == null) - continue; - String message = FIND_CMD + " " + name; - if (replyAddr == null) - message += " " + interfaceAddress.getAddress().getHostAddress() + " " + socket.getLocalPort(); - else - message += " " + replyAddr.getHostAddress() + " " + replyPort; - message += " " + hop; - - byte[] sendData = message.getBytes(); - - // Send the broadcast packet. - try - { - //System.out.println("Send to " + broadcast.getHostAddress() + " port " + DISCOVERY_PORT ); - DatagramPacket sendPacket = new DatagramPacket( - sendData, sendData.length, broadcast, DISCOVERY_PORT); - socket.send(sendPacket); - } catch (Exception e) - { - System.err - .println("Exception sending to : " - + networkInterface.getDisplayName() - + " : " + e); - } - } - } - } catch (IOException ex) - { - System.err.println("Exception opening socket : " + ex); - } - } - - /** - * Search for a named EV3. Return a table of the addresses that can be used to contact - * the device. An empty table is returned if no EV3s are found. - * @param name - * @return A table of matching devices - */ - public static BrickInfo[] find(String name) - { - DatagramSocket socket=null; - Map ev3s = new HashMap(); - try - { - socket = new DatagramSocket(); - socket.setBroadcast(true); - boolean findAll = name.equalsIgnoreCase("*"); - broadcastFindRequest(socket, name, null, -1, MAX_HOPS); - socket.setSoTimeout(MAX_DISCOVERY_TIME/4); - DatagramPacket packet = new DatagramPacket (new byte[MAX_PACKET_SIZE], MAX_PACKET_SIZE); - - long start = System.currentTimeMillis(); - - while ((System.currentTimeMillis() - start) < MAX_DISCOVERY_TIME) { - try { - socket.receive (packet); - String message = new String(packet.getData(), "UTF-8").trim(); - if (findAll || message.equalsIgnoreCase(name)) - { - String ip = packet.getAddress().getHostAddress(); - ev3s.put(ip, new BrickInfo(message.trim(),ip,"EV3")); - } - } catch (SocketTimeoutException e) - { - // No response ask again - broadcastFindRequest(socket, name, null, -1, MAX_HOPS); - } - } - } catch (IOException ex) - { - System.err.println("Exception opening socket : " + ex); - } finally - { - if (socket != null) - socket.close(); - } - BrickInfo[] devices = new BrickInfo[ev3s.size()]; - int i = 0; - - for(String ev3: ev3s.keySet()) { - devices[i++] = ev3s.get(ev3); - } - return devices; - } - - - /** - * Search for available EV3s and populate table with results. - */ - public static BrickInfo[] discover() { - return find("*"); - } - - public static BrickInfo[] discoverNXT() { - try { - Collection nxts = Bluetooth.getLocalDevice().search(); - BrickInfo[] bricks = new BrickInfo[nxts.size()]; - int i = 0; - for(RemoteBTDevice d: nxts) { - BrickInfo b = new BrickInfo(d.getName(), d.getAddress(), "NXT"); - bricks[i++] = b; - } - return bricks; - } catch (Exception e) { - throw new DeviceException("Error finding remote NXTs", e); - } - } - - public static void setDefault(Brick brick) { - defaultBrick = brick; - } - - - /** - * Start the discovery server running. There should be a single discovery server - * running on each EV3. This provides responses to remote discover and find - * requests. Normally this server will be run by the leJOS menu and so user code - * does not need to start a copy. - * @param forward true if requests should be forwarded to other devices - */ - public static void startDiscoveryServer(boolean forward) - { - DiscoveryServer.start(forward); - } - - /** - * Stop the discovery server - */ - public static void stopDiscoveryServer() - { - DiscoveryServer.stop(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/BrickInfo.java b/ev3classes/src/main/java/lejos/hardware/BrickInfo.java deleted file mode 100644 index 8165757..0000000 --- a/ev3classes/src/main/java/lejos/hardware/BrickInfo.java +++ /dev/null @@ -1,25 +0,0 @@ -package lejos.hardware; - -public class BrickInfo { - private String name; - private String ipAddress; - private String type; - - public BrickInfo(String name, String ipAddress, String type) { - this.name = name; - this.ipAddress = ipAddress; - this.type = type; - } - - public String getName() { - return name; - } - - public String getIPAddress() { - return ipAddress; - } - - public String getType() { - return type; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Button.java b/ev3classes/src/main/java/lejos/hardware/Button.java deleted file mode 100644 index 15ca747..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Button.java +++ /dev/null @@ -1,228 +0,0 @@ -package lejos.hardware; - -/** - * Abstraction for an NXT button. Example: - * - *
- * Button.ENTER.waitForPressAndRelease();
- * Sound.playTone(1000, 1);
- * 
- * - * Notions: The API is designed around two notions: states (up / down) - * and events (press / release). It is said that a button is pressed (press - * event), if its state changes from up to down. Similarly, it is said that a - * button is released (release event), if its states changed from down to up. - * - * Thread Safety: All methods that return buttons states can be used - * safely from multiple threads, even while a call to one of the waitFor* - * methods active. However, it is not safe to invoke waitFor* methods in - * parallel from different threads. This includes the waitFor* methods of - * different buttons. For example Button.ENTER.waitForPress() must not be - * invoked in parallel to Button.ESCAPE.waitForPress() or the static - * Button.waitForAnyEvent(). In case this is needed, it is strongly recommended - * that you write your own Thread, which waits for button events and dispatches - * the events to anyone who's interested. - */ -public class Button { - - public static final int ID_UP = 0x1; - public static final int ID_ENTER = 0x2; - public static final int ID_DOWN = 0x4; - public static final int ID_RIGHT = 0x8; - public static final int ID_LEFT = 0x10; - public static final int ID_ESCAPE = 0x20; - public static final int ID_ALL = 0x3f; - - public static final String VOL_SETTING = "lejos.keyclick_volume"; - public static final String LEN_SETTING = "lejos.keyclick_length"; - public static final String FREQ_SETTING = "lejos.keyclick_frequency"; - - /** - * The Enter button. - */ - public static final Key ENTER = BrickFinder.getDefault().getKey("Enter"); - /** - * The Left button. - */ - public static final Key LEFT = BrickFinder.getDefault().getKey("Left"); - /** - * The Right button. - */ - public static final Key RIGHT = BrickFinder.getDefault().getKey("Right"); - /** - * The Escape button. - */ - public static final Key ESCAPE = BrickFinder.getDefault().getKey("Escape"); - /** - * The Up button. - */ - public static final Key UP = BrickFinder.getDefault().getKey("Up"); - /** - * The Down button. - */ - public static final Key DOWN = BrickFinder.getDefault().getKey("Down"); - - public static final Keys keys = BrickFinder.getDefault().getKeys(); - - private Button(int aCode) { - // Don't use - } - - /** - * This method discards any events. In contrast to {@link #readButtons()}, - * this method doesn't beep if a button is pressed. - */ - public static void discardEvents() { - keys.discardEvents(); - } - - /** - * Waits for some button to be pressed or released. Which buttons have been - * released or pressed is returned as a bitmask. The lower eight bits (bits - * 0 to 7) indicate, which buttons have been pressed. Bits 8 to 15 indicate - * which buttons have been released. - * - * @return the bitmask - * @see #ID_ENTER - * @see #ID_LEFT - * @see #ID_RIGHT - * @see #ID_ESCAPE - */ - public static int waitForAnyEvent() { - return keys.waitForAnyEvent(); - } - - /** - * Waits for some button to be pressed or released. Which buttons have been - * released or pressed is returned as a bitmask. The lower eight bits (bits - * 0 to 7) indicate, which buttons have been pressed. Bits 8 to 15 indicate - * which buttons have been released. - * - * @param timeout - * The maximum number of milliseconds to wait - * @return the bitmask - * @see #ID_ENTER - * @see #ID_LEFT - * @see #ID_RIGHT - * @see #ID_ESCAPE - */ - public static int waitForAnyEvent(int timeout) { - return keys.waitForAnyEvent(timeout); - } - - /** - * Waits for some button to be pressed. If a button is already pressed, it - * must be released and pressed again. - * - * @param timeout - * The maximum number of milliseconds to wait - * @return the ID of the button that has been pressed or in rare cases a - * bitmask of button IDs, 0 if the given timeout is reached - */ - public static int waitForAnyPress(int timeout) { - return keys.waitForAnyPress(timeout); - } - - /** - * Waits for some button to be pressed. If a button is already pressed, it - * must be released and pressed again. - * - * @return the ID of the button that has been pressed or in rare cases a - * bitmask of button IDs - */ - public static int waitForAnyPress() { - return waitForAnyPress(0); - } - - /** - * Low-level API that reads status of buttons. - * - * @return An integer with possibly some bits set: {@link #ID_ENTER} (ENTER - * button pressed) {@link #ID_LEFT} (LEFT button pressed), - * {@link #ID_RIGHT} (RIGHT button pressed), {@link #ID_ESCAPE} - * (ESCAPE button pressed). If all buttons are released, this method - * returns 0. - */ - public static int getButtons() { - return keys.getButtons(); - } - - /** - * Low-level API that reads status of buttons. - * - * @return An integer with possibly some bits set: {@link #ID_ENTER} (ENTER - * button pressed) {@link #ID_LEFT} (LEFT button pressed), - * {@link #ID_RIGHT} (RIGHT button pressed), {@link #ID_ESCAPE} - * (ESCAPE button pressed). If all buttons are released, this method - * returns 0. - */ - public static int readButtons() { - return keys.readButtons(); - } - - /** - * Set the volume used for key clicks - * - * @param vol - */ - public static void setKeyClickVolume(int vol) { - keys.setKeyClickVolume(vol); - } - - /** - * Return the current key click volume. - * - * @return current click volume - */ - public static synchronized int getKeyClickVolume() { - return keys.getKeyClickVolume(); - } - - /** - * Set the len used for key clicks - * - * @param len - * the click duration - */ - public static synchronized void setKeyClickLength(int len) { - keys.setKeyClickLength(len); - } - - /** - * Return the current key click length. - * - * @return key click duration - */ - public static synchronized int getKeyClickLength() { - return keys.getKeyClickLength(); - } - - /** - * Set the frequency used for a particular key. Setting this to 0 disables - * the click. Note that key may also be a corded set of keys. - * - * @param key - * the NXT key - * @param freq - * the frequency - */ - public static synchronized void setKeyClickTone(int key, int freq) { - keys.setKeyClickTone(key, freq); - } - - /** - * Return the click freq for a particular key. - * - * @param key - * The key to obtain the tone for - * @return key click duration - */ - public static synchronized int getKeyClickTone(int key) { - return keys.getKeyClickTone(key); - } - - public static void LEDPattern(int pattern) { - BrickFinder.getDefault().getLED().setPattern(pattern); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/Device.java b/ev3classes/src/main/java/lejos/hardware/Device.java deleted file mode 100644 index f1f5f44..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Device.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.hardware; - -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; - - -/** - * Base class for sensor drivers. Provides mechanism to release resources when closed - * @author andy - * - */ -public class Device implements Closeable -{ - protected ArrayList closeList = new ArrayList(); - - /** - * Add the specified resource to the list of objects that will be closed - * when the sensor is closed. - * @param res - */ - protected void releaseOnClose(Closeable res) - { - closeList.add(res); - } - - /** - * Close the sensor. Close associated resources. - - */ - @Override - public void close() - { - for(Closeable res : closeList) - try { - res.close(); - } catch(IOException e) - { - // this really should not happen - throw new DeviceException("Error during close", e); - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/DeviceException.java b/ev3classes/src/main/java/lejos/hardware/DeviceException.java deleted file mode 100644 index bc05733..0000000 --- a/ev3classes/src/main/java/lejos/hardware/DeviceException.java +++ /dev/null @@ -1,33 +0,0 @@ -package lejos.hardware; - -/** - * Exception thrown when errors are detected in a sensor device state. - * @author andy - * - */ -public class DeviceException extends RuntimeException -{ - /** - * - */ - private static final long serialVersionUID = 5846698127613306496L; - - public DeviceException() - { - } - - public DeviceException(String message) - { - super (message); - } - - public DeviceException(Throwable cause) - { - super (cause); - } - - public DeviceException(String message, Throwable cause) - { - super (message, cause); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Key.java b/ev3classes/src/main/java/lejos/hardware/Key.java deleted file mode 100644 index 0f50883..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Key.java +++ /dev/null @@ -1,32 +0,0 @@ -package lejos.hardware; - -public interface Key { - - public static final int UP = 0; - public static final int ENTER = 1; - public static final int DOWN = 2; - public static final int RIGHT = 3; - public static final int LEFT = 4; - public static final int ESCAPE = 5; - - public static int KEY_RELEASED = 0; - public static int KEY_PRESSED = 1; - public static int KEY_PRESSED_AND_RELEASED = 2; - - public int getId(); - - public boolean isDown(); - - public boolean isUp(); - - public void waitForPress(); - - public void waitForPressAndRelease(); - - public void addKeyListener (KeyListener listener); - - public void simulateEvent(int event); - - public String getName(); - -}; diff --git a/ev3classes/src/main/java/lejos/hardware/KeyListener.java b/ev3classes/src/main/java/lejos/hardware/KeyListener.java deleted file mode 100644 index 8ff7456..0000000 --- a/ev3classes/src/main/java/lejos/hardware/KeyListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package lejos.hardware; - -public interface KeyListener { - - public void keyPressed (Key k); - - public void keyReleased (Key k); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/Keys.java b/ev3classes/src/main/java/lejos/hardware/Keys.java deleted file mode 100644 index 8913bba..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Keys.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.hardware; - -public interface Keys { - - public static final int ID_UP = 0x1; - public static final int ID_ENTER = 0x2; - public static final int ID_DOWN = 0x4; - public static final int ID_RIGHT = 0x8; - public static final int ID_LEFT = 0x10; - public static final int ID_ESCAPE = 0x20; - public static final int ID_ALL = 0x3f; - - public static int NUM_KEYS = 6; - - public static final String VOL_SETTING = "lejos.keyclick_volume"; - public static final String LEN_SETTING = "lejos.keyclick_length"; - public static final String FREQ_SETTING = "lejos.keyclick_frequency"; - - public void discardEvents(); - - public int waitForAnyEvent(); - - public int waitForAnyEvent(int timeout); - - public int waitForAnyPress(int timeout); - - public int waitForAnyPress(); - - public int getButtons(); - - public int readButtons(); - - public void setKeyClickVolume(int vol); - - public int getKeyClickVolume(); - - public void setKeyClickLength(int len); - - public int getKeyClickLength(); - - public void setKeyClickTone(int key, int freq); - - public int getKeyClickTone(int key); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/LED.java b/ev3classes/src/main/java/lejos/hardware/LED.java deleted file mode 100644 index 4ba47ab..0000000 --- a/ev3classes/src/main/java/lejos/hardware/LED.java +++ /dev/null @@ -1,7 +0,0 @@ -package lejos.hardware; - -public interface LED { - - public void setPattern(int pattern); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/ListenerCaller.java b/ev3classes/src/main/java/lejos/hardware/ListenerCaller.java deleted file mode 100644 index 7e7e511..0000000 --- a/ev3classes/src/main/java/lejos/hardware/ListenerCaller.java +++ /dev/null @@ -1,9 +0,0 @@ -package lejos.hardware; - -/** - * Interface for calling calling lejos listeners. - */ -public interface ListenerCaller { - int callListeners(); -} - diff --git a/ev3classes/src/main/java/lejos/hardware/LocalBTDevice.java b/ev3classes/src/main/java/lejos/hardware/LocalBTDevice.java deleted file mode 100644 index eba38fc..0000000 --- a/ev3classes/src/main/java/lejos/hardware/LocalBTDevice.java +++ /dev/null @@ -1,173 +0,0 @@ -package lejos.hardware; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.sun.jna.LastErrorException; - -import lejos.internal.dbus.DBusBluez; -import lejos.internal.io.NativeHCI; - -public class LocalBTDevice { - private NativeHCI hci = new NativeHCI(); - private DBusBluez db; - - public LocalBTDevice() { - try { - db = new DBusBluez(); - } catch (Exception e) { - System.err.println("Failed to create DBusJava: " + e); - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Search for and return a list of Bluetooth devices. - * @return The found devices. - * @throws IOException - */ - public Collection search() { - try { - Collection results = hci.hciInquiry(); - for(RemoteBTDevice d: results) { - System.out.println("Found " + d.getName()); - } - return results; - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Return a list of the devices we are paired with - * @return the list of paired devices - */ - public Collection getPairedDevices() { - try { - List devices = db.retrieveDevices(true); - Collection result = new ArrayList(); - for(String d: devices) { - RemoteBTDevice rd = new RemoteBTDevice(db.getDeviceName(d), Bluetooth.getAddress(d), db.getDeviceClass(d)); - result.add(rd); - } - return result; - } catch (Exception e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Set the visibility state of the device - * @param visible new visibility state - */ - public void setVisibility(boolean visible) { - try { - hci.hciSetVisible(visible); - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * return the current visibility of the device - * @return true if the device is visible - */ - public boolean getVisibility() { - try { - return hci.hcigetVisible(); - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Check to see if the device is currently powered on - * @return true if the device is on - */ - public static boolean isPowerOn() { - return true; - } - - /** - * Return the address of the local device - * @return A string version of the Bluetooth device address - */ - public String getBluetoothAddress() { - try { - return Bluetooth.getAddress(getDeviceInfo().bdaddr); - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Return the name of the local device - * @return A string containing the device name - */ - public String getFriendlyName() { - try { - return db.getAdapterName(); - } catch (Exception e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Return a structure providing information about the local device - * @return local device information - */ - public NativeHCI.DeviceInfo getDeviceInfo() { - try { - return hci.hciGetDeviceInfo(); - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * return a structure providing local version information - * @return local version information - */ - public NativeHCI.LocalVersion getLocalVersion() { - try { - return hci.hciGetLocalVersion(); - } catch (LastErrorException e) { - throw(new BluetoothException(e.getMessage(), e)); - } - - } - - /** - * Authenticate/pair the local device with the specified device - * @param deviceAddress address of the device to pair with - * @param pin Pin to use for pairing with the device - */ - public void authenticate(String deviceAddress, String pin) { - try { - db.authenticateRemoteDevice(deviceAddress, pin); - } catch (Exception e) { - System.err.println("Failed to authenticate remote device: " + e); - throw(new BluetoothException(e.getMessage(), e)); - } - } - - /** - * Remove the specified device from the known/paired list - * @param deviceAddress address of the device to remove - */ - public void removeDevice(String deviceAddress) { - try { - db.removeAuthenticationWithRemoteDevice(deviceAddress); - } catch (Exception e) { - System.err.println("Failed to remove device: " + e); - throw(new BluetoothException(e.getMessage(), e)); - } - } - - public void disconnect() - { - db.disconnect(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/LocalWifiDevice.java b/ev3classes/src/main/java/lejos/hardware/LocalWifiDevice.java deleted file mode 100644 index 5461b37..0000000 --- a/ev3classes/src/main/java/lejos/hardware/LocalWifiDevice.java +++ /dev/null @@ -1,112 +0,0 @@ -package lejos.hardware; - -import java.util.HashSet; - -import com.sun.jna.Memory; - -import lejos.internal.io.NativeWifi; -import lejos.utility.Delay; - -public class LocalWifiDevice { - private String ifName; - private NativeWifi wifi = new NativeWifi(); - NativeWifi.WReqPoint reqP = new NativeWifi.WReqPoint(); - NativeWifi.WReqSocket reqS = new NativeWifi.WReqSocket(); - HashSet results; - - LocalWifiDevice(String ifName) { - this.ifName = ifName; - } - - public String[] getAccessPointNames() { - results = new HashSet(); - - System.out.println("Starting a scan"); - - // Copy the name to the request structure - System.arraycopy(ifName.getBytes(), 0, reqP.ifname, 0, ifName.length()); - - int ret = wifi.ioctl(NativeWifi.SIOCSIWSCAN , reqP); - System.out.println("ioctl ret is " + ret); - if (ret >= 0) { - // Wait for the results - - Delay.msDelay(1000); - - // Create buffer for the results - - reqP.point.flags = 0; - reqP.point.length = 8192; - reqP.point.p = new Memory(reqP.point.length); - - // Get the results - - System.out.println("Getting the results"); - // wait for the results to be available - // TODO: This code is very ugly. We should probably either use - // exceptions or use return codes not both! - ret = -1; - int retryCnt = 30; - while (ret < 0) - { - try { - ret = wifi.ioctl(NativeWifi.SIOCGIWSCAN , reqP); - } catch (RuntimeException e) - { - if (retryCnt <= 0) - throw e; - ret = -1; - System.out.println("Got error retry cnt " + retryCnt); - } - Delay.msDelay(1000); - retryCnt--; - } - System.out.println("get results returns " + ret); - if (ret >= 0) { - int offset= 0; - while(offset < reqP.point.length) { - int len = reqP.point.p.getShort(offset); - int ev = reqP.point.p.getShort(offset+2) & 0xFFFF; - - if (ev == NativeWifi.SIOCGIWESSID) { - - StringBuilder sb = new StringBuilder(); - for(int j=0;j 0 ) { - - StringBuilder sb = new StringBuilder(); - - sb = new StringBuilder(); - for(int j=0;j<6;j++) { - String hex = Integer.toHexString(reqS.sockaddr.bd_addr[j] & 0xFF).toUpperCase(); - if (hex.length() == 1) sb.append('0'); - sb.append(hex); - if (j<5) sb.append(':'); - } - - System.out.println("Access Point:" + sb.toString()); - - return sb.toString(); - } - return null; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Power.java b/ev3classes/src/main/java/lejos/hardware/Power.java deleted file mode 100644 index f81cbdb..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Power.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.hardware; - -/** - * Interface used to access information about the EV3 battery and current usage. - * @author Brian Bagnall, Lawrie Griffiths Andy Shaw - * - */ -public interface Power { - - /** - * The NXT uses 6 batteries of 1500 mV each. - * @return Battery voltage in mV. ~9000 = full. - */ - public int getVoltageMilliVolt(); - - /** - * The NXT uses 6 batteries of 1.5 V each. - * @return Battery voltage in Volt. ~9V = full. - */ - public float getVoltage(); - - /** - * Return the current draw from the battery - * @return current in Amps - */ - public float getBatteryCurrent(); - - /** - * return the motor current draw - * @return current in Amps - */ - public float getMotorCurrent(); -} - diff --git a/ev3classes/src/main/java/lejos/hardware/RemoteBTDevice.java b/ev3classes/src/main/java/lejos/hardware/RemoteBTDevice.java deleted file mode 100644 index dcf0266..0000000 --- a/ev3classes/src/main/java/lejos/hardware/RemoteBTDevice.java +++ /dev/null @@ -1,37 +0,0 @@ -package lejos.hardware; - -import java.io.Serializable; - -public class RemoteBTDevice implements Serializable { - - private static final long serialVersionUID = -1668354353670941450L; - private String name; - private byte[] address; - private int cod; - - public RemoteBTDevice(String name, byte[] address, int cod) { - this.name = name; - this.address = address; - this.cod = cod; - } - - public String getName() { - return name; - } - - public byte[] getDeviceAddress() { - return address; - } - - public int getDeviceClass() { - return cod; - } - - public String getAddress() { - return Bluetooth.getAddress(address); - } - - public void authenticate(String pin) { - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Sound.java b/ev3classes/src/main/java/lejos/hardware/Sound.java deleted file mode 100644 index 2c94692..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Sound.java +++ /dev/null @@ -1,221 +0,0 @@ -package lejos.hardware; - -import java.io.*; - -import lejos.utility.Delay; - -/** - * Class that provides access methods for the local audio device - * - */ -public class Sound implements Sounds -{ - protected final static Audio audio = BrickFinder.getDefault().getAudio(); - // TODO: We should probably not have the following. Add a saveProperties method? - public final static String VOL_SETTING = "lejos.volume"; - - private Sound() - { - } - - public static int C2 = 523; - - /** - * Play a system sound. - * - * - * - * - * - * - * - *
aCodeResulting Sound
0short beep
1double beep
2descending arpeggio
3ascending arpeggio
4long, low buzz
- */ - public static void systemSound(boolean aQueued, int aCode) - { - audio.systemSound(aCode); - - } - - /** - * Beeps once. - */ - public static void beep() - { - systemSound(true, BEEP); - } - - /** - * Beeps twice. - */ - public static void twoBeeps() - { - systemSound(true, DOUBLE_BEEP); - } - - /** - * Downward tones. - */ - public static void beepSequence() - { - systemSound(true, DESCENDING); - } - - /** - * Upward tones. - */ - public static void beepSequenceUp() - { - systemSound(true, ASCENDING); - } - - /** - * Low buzz - */ - public static void buzz() - { - systemSound(true, BUZZ); - } - - public static void pause(int t) - { - Delay.msDelay(t); - } - - /** - * Returns the number of milliseconds remaining of the current tone or sample. - * @return milliseconds remaining - */ - public static int getTime() - { - return 0; - } - - - /** - * Plays a tone, given its frequency and duration. - * @param aFrequency The frequency of the tone in Hertz (Hz). - * @param aDuration The duration of the tone, in milliseconds. - * @param aVolume The volume of the playback 100 corresponds to 100% - */ - public static void playTone(int aFrequency, int aDuration, int aVolume) - { - audio.playTone(aFrequency, aDuration, aVolume); - } - - /** - * Plays a tone, given its frequency and duration. - * @param freq The frequency of the tone in Hertz (Hz). - * @param duration The duration of the tone, in milliseconds. - */ - public static void playTone(int freq, int duration) - { - audio.playTone(freq, duration); - } - - /** - * Play a wav file. Must be mono, from 8kHz to 48kHz, and 8-bit or 16-bit. - * @param file the 8-bit or 16-bit PWM (WAV) sample file - * @param vol the volume percentage 0 - 100 - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public static int playSample(File file, int vol) - { - return audio.playSample(file, vol); - } - - - /** - * Play a wav file. Must be mono, from 8kHz to 48kHz, and 8-bit or 16-bit. - * @param file the 8-bit or 16-bit PWM (WAV) sample file - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public static int playSample(File file) - { - return audio.playSample(file); - } - - - /** - * Queue a series of PCM samples to play at the - * specified volume and sample rate. - * - * @param data Buffer containing the samples - * @param offset Offset of the first sample in the buffer - * @param len Number of samples to queue - * @param freq Sample rate - * @param vol playback volume - * @return Number of samples actually queued - */ - public static int playSample(byte [] data, int offset, int len, int freq, int vol) - { - return audio.playSample(data, offset, len, freq, vol); - - } - - /** - *

Play a note with attack, decay, sustain and release shape, which is known as - * a ADSR envelope. This function plays a more musical sounding note compared to - * playTone(). It uses a set of supplied "instrument" parameters to define the - * shape of the note's envelope.

- * - *

Instruments are defined in the Sounds interface, which is inherited by this class. - * For example, the piano instrument array looks like this:

- * public final static int[] PIANO = new int[]{4, 25, 500, 7000, 5}; - * - *

The parameter len is the total time of the note to be played - * val 0 is the attack time the time for the volume to go from near zero to 100% - * val 1 is the decay time during this period the volume decreases by val[2]/100 - * to the sustain level. - * the sustain period is (len - val[0] - val[1] - val[4]) during this period the - * volume decreases by val[3]/100. - * the final decay period is val[4] and the volume reduces to zero. - * All of the times are units of 2mS (except for len which is in mS).

- *

Because values equal 2ms, the piano array numbers are doubled:
- * 1. take 8mS to increase the volume from zero to 100%
- * 2. take 50mS to decrese the volume by 5%
- * 3. take len - 8 - 25 - 10 mS to decrease the volume by 70%
- * 4. take 10mS to decrease the volume to 0

- * - * @param inst Instrument definition (5 ints in an array). - * @param freq The note to play (in Hz) - * @param len The duration of the note (in ms) - */ - public static void playNote(int[] inst, int freq, int len) - { - audio.playNote(inst, freq, len); - - } - - /** - * Set the master volume level - * @param vol 0-100 - */ - public static void setVolume(int vol) - { - audio.setVolume(vol); - } - - /** - * Get the current master volume level - * @return the current master volume 0-100 - */ - public static int getVolume() - { - return audio.getVolume(); - } - - /** - * Load the current system settings associated with this class. Called - * automatically to initialize the class. May be called if it is required - * to reload any settings. - */ - public static void loadSettings() - { - audio.loadSettings(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/Sounds.java b/ev3classes/src/main/java/lejos/hardware/Sounds.java deleted file mode 100644 index b2dfa84..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Sounds.java +++ /dev/null @@ -1,19 +0,0 @@ -package lejos.hardware; - -public interface Sounds -{ - // Instruments (yes I know they don't sound anything like the names!) - public final static int[] PIANO = new int[]{4, 25, 500, 7000, 5}; - public final static int[] FLUTE = new int[]{10, 25, 2000, 1000, 25}; - public final static int[] XYLOPHONE = new int[]{1, 8, 3000, 5000, 5}; - - public final static int BEEP = 0; - public final static int DOUBLE_BEEP = 1; - public final static int ASCENDING = 2; - public final static int DESCENDING = 3; - public final static int BUZZ = 4; - - public static final int VOL_MAX = 100; - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/Wifi.java b/ev3classes/src/main/java/lejos/hardware/Wifi.java deleted file mode 100644 index 93736a9..0000000 --- a/ev3classes/src/main/java/lejos/hardware/Wifi.java +++ /dev/null @@ -1,32 +0,0 @@ -package lejos.hardware; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; - -public class Wifi { - public static LocalWifiDevice getLocalDevice(String ifName) { - return new LocalWifiDevice(ifName); - } - - public static String[] getIfNames() throws IOException { - ArrayList results = new ArrayList(); - BufferedReader br = new BufferedReader(new FileReader("/proc/net/wireless")); - String s; - br.readLine(); - br.readLine(); - - int n=0; - while ((s = br.readLine()) != null) { - String [] ss = s.split(":"); - String ifn = ss[0].trim(); - System.out.println("Interface " + n++ + " is " + ifn); - results.add(ifn); - } - - br.close(); - return results.toArray(new String[results.size()]); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/DLight.java b/ev3classes/src/main/java/lejos/hardware/device/DLight.java deleted file mode 100644 index 5a1cff6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/DLight.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.hardware.device; - -/** - * Interface for dLights from Dexter Industries - * @author Aswin Bouwmeester - * - */ -public interface DLight { - - /** - * Enables the dLight. - */ - public void enable(); - - /** - * Disables the dLight. - * Values for color and blinking pattern are not overwritten and will - * still be in effect after enabling the dLight again. - */ - public void disable(); - - /** Queries the status of the dLight - * @return - * True, the dLight is enabled. False, the dLight is off. - */ - public boolean isEnabled(); - - /** - * Changes the color of the LED according to specified RGB color. - * Each of the color values should be between 0 (fully off) and 255 (fully on). - * @param red - * @param green - * @param blue - */ - public void setColor(int red, int green, int blue); - - /** - * Changes the color of the LED according to specified RGB color. - * Each of the color values should be between 0 (fully off) and 255 (fully on). - * @param rgb - * Integer array containing RGB colors - */ - public void setColor(int[] rgb); - - /** - * Changes the color of the LED according to specified HSL color. - * @param hue - * The hue value in the range of 0-360 - * @param saturation - * The saturation value in the range of 0-100 - * @param luminosity - * The saturation luminosity value in the range of 0-100 - */ - public void setHSLColor(int hue, int saturation, int luminosity); - - /** - * Specifies the blinking pattern of the LED. Blinnking mode should be enabled - * for the pattern to be in effect. - * @param seconds - * The total time of a blinking cycle (in seconds) - * @param percentageOn - * The percentage of the time the LED is on within a blinking cycle - */ - public void setBlinkingPattern(float seconds, int percentageOn); - - /** - * Enables blinking pattern. The blinking pattern should be set with the SetBlinkingPattern method. - */ - public void enableBlinking(); - - /** - * Disables blinking. The blinking pattern itself remains in memory. - */ - public void disableBlinking(); - - /** - * Queries the blinking mode of the dLight - * @return - * True is blinking is enabled. False if blinking is disabled. - */ - public boolean isBlinkingEnabled(); - - /** - * Returns the RGB color of the LED - * Each of the color values is between 0 (fully off) and 255 (fully on). - * @param rgb - */ - public void getColor(int[] rgb); - - /** - * Sets the PWM value of the external LED driver of the dLight. - * Each dLight has two leads broken out that can be used to drive an external LED. - * @param value - * The values should be between 0 (fully off) and 255 (fully on). - */ - public void setExternalLED(int value); - - /** - * Gets the PWM value of the external LED driver of the dLight. - * Each dLight has two leads broken out that can be used to drive an external LED. - * @return - * The return value is between 0 (fully off) and 255 (fully on). - */ - public int getExternalLED(); - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/DLights.java b/ev3classes/src/main/java/lejos/hardware/device/DLights.java deleted file mode 100644 index bb7d755..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/DLights.java +++ /dev/null @@ -1,431 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * The DLights class drives up to four dLights on a single sensor port. - *

- * The dLight is a RGB color LED connected to a sensor port. - * Up to four dLights can be daisy chained on a single port. - * The individual dLights are identified within this class by a sequence number (1-4). - * All dLights can be addressed simultaniously as a group by using sequence number 0. - *

- * The DLights class supports two different color schemes for instructing the dLights; RGB and HSL. - * It supports just RGB for querying the dLights - * - * @author Aswin Bouwmeester - * - */ -public class DLights { - - private LED[] dLights = new LED[5]; - private final int[] address = { 0xe0, 0x04, 0x14, 0x24, 0x34 }; - - /** - * Constructor for DLights.

Nb. It also enables HIGH-SPEED I2C on this port. - * - * @param port - * The I2CPort that the dLights are attached to. - */ - public DLights(I2CPort port) { - for (int i = 0; i < 5; i++) - dLights[i] = new LED(port, address[i]); - } - - public DLights(Port port) { - for (int i = 0; i < 5; i++) - dLights[i] = new LED(port, address[i]); - } - - /** - * Returns the I2C driver for a single dLight. - *

- * Nb. For ordinary use there is no need to use the I2C driver for a single - * dLight that this method returns. The method and the DLight instance it - * returns are nly useful if one needs to access the dLight directly over I2C. - * - * @param lightNo - * The sequence number of the dLight (1-4). Please note that the group number 0 is invalid for this method. - * @return the I2C driver for a single dLight - */ - public DLight getDLight(int lightNo) { - if (1>lightNo || lightNo>4) - throw new IllegalArgumentException(); - return dLights[lightNo]; - } - - /** - * Enables the dLight.

- * - * @param lightNo - * The sequence number of the dLight (0-4). - */ - public void enable(int lightNo) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].enable(); - } - - /** - * Disables the dLight. The light will be off, no matter what values for color are sent to the dLight. - *

Values for color and blinking pattern are not overwritten and will still be in effect after enabling the dLight again. - * - * @param lightNo - * The sequence number of the dLight (0-4). - */ - public void disable(int lightNo) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].disable(); - } - - /** Queries the status of the dLight - * @param lightNo (1-4). Please note that the group number 0 is invalid for this method. - * @return - * True, the dLight is enabled. False, the dLight is off. - */ - public boolean isEnabled(int lightNo) { - if (1>lightNo || lightNo>4) - throw new IllegalArgumentException(); - return dLights[lightNo].isEnabled(); - } - - /** - * Changes the color of the LED according to specified RGB color. Each of the - * color values should be between 0 (fully off) and 255 (fully on). - * - * @param lightNo - * The sequence number of the dLight (0-4). - * @param red - * @param green - * @param blue - */ - public void setColor(int lightNo, int red, int green, int blue) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].setColor(red, green, blue); - } - - /** - * Changes the color of the LED according to specified RGB color. Each of the - * color values should be between 0 (fully off) and 255 (fully on). - * - * @param lightNo - * The sequence number of the dLight (0-4). - * @param rgb - * an integer array containing RGB colors - */ - public void setColor(int lightNo, int[] rgb) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].setColor(rgb); - } - - - /** - * Changes the color of the LED according to specified HSL color. - * - * @param hue - * The hue value in the range of 0-360 - * @param saturation - * The saturation value in the range of 0-100 - * @param luminosity - * The saturation luminosity value in the range of 0-100 - */ - public void setHSLColor(int lightNo, int hue, int saturation, int luminosity) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].setHSLColor(hue, saturation, luminosity); - } - - /** - * Specifies the blinking pattern of the LED. Blinnking mode should be enabled - * for the pattern to be in effect. - * - * @param lightNo - * The sequence number of the dLight (0-4). - * @param seconds - * The total time of a blinking cycle (in seconds) - * @param percentageOn - * The percentage of the time the LED is on within a blinking cycle - */ - public void setBlinkingPattern(int lightNo, float seconds, int percentageOn) { - if (0>lightNo || lightNo>4 || seconds>10.0f || seconds < 0.04f || percentageOn<0 ||percentageOn>100) - throw new IllegalArgumentException(); - dLights[lightNo].setBlinkingPattern(seconds, percentageOn); - } - - /** - * Enables blinking pattern. The blinking pattern should be set with the - * SetBlinkingPattern method. - * - * @param lightNo - * The sequence number of the dLight (0-4). - */ - public void enableBlinking(int lightNo) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].enableBlinking(); - } - - /** - * Disables blinking. The blinking pattern itself remains in memory. - * - * @param lightNo - * The sequence number of the dLight (0-4). - */ - public void disableBlinking(int lightNo) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].disableBlinking(); - } - - /** Queries the blinking status of the dLight - * @param lightNo (1-4). Please note that the group number 0 is invalid for this method. - * @return - * True, blinking is enabled. False, blinking is disabled. - */ - public boolean isBlinkingEnabled(int lightNo) { - if (1>lightNo || lightNo>4) - throw new IllegalArgumentException(); - return dLights[lightNo].isBlinkingEnabled(); - } - - - /** - * Returns the RGB color of the LED Each of the color values is between 0 - * (fully off) and 255 (fully on). - * - * @param lightNo - * The sequence number of the dLight (1-4). Please note that the group number 0 is invalid for this method. - * @param rgb - * the RGB color of the LED - */ - public void getColor(int lightNo, int[] rgb) { - if (1>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].getColor(rgb); - } - - /** - * Sets the PWM value of the external LED driver of the dLight. Each dLight - * has two leads broken out that can be used to drive an external LED. - * - * @param lightNo - * The sequence number of the dLight (0-4). - * @param value - * The values should be between 0 (fully off) and 255 (fully on). - */ - public void setExternalLED(int lightNo, int value) { - if (0>lightNo || lightNo>4) - throw new IllegalArgumentException(); - dLights[lightNo].setExternalLED(value); - } - - /** - * Gets the PWM value of the external LED driver of the dLight. Each dLight - * has two leads broken out that can be used to drive an external LED. - * - * @param lightNo - * The sequence number of the dLight (1-4). Please note that the group number 0 is invalid for this method. - * @return The return value is between 0 (fully off) and 255 (fully on). - */ - public int getExternalLED(int lightNo) { - if (1>lightNo || lightNo>4) - throw new IllegalArgumentException(); - return dLights[lightNo].getExternalLED(); - } - - /** - * This is the I2C driver for a single (or group of) dLights. If this class - * represents a group then all dLights respond to it's methods. - * - * @author Aswin - * - */ - private class LED extends I2CSensor implements DLight { - // Registers - private static final int MODE1 = 0x00; - private static final int MODE2 = 0x01; - private static final int COLOR = 0x02; - private static final int EXTERNAL = 0x05; - private static final int GRPPWM = 0x06; - private static final int GRPFREQ = 0x07; - private static final int LEDOUT = 0x08; - private static final int AUTOINCREMENT = 0x80; - - // Common register values - private static final byte MODE1MASK = 0x01; - private static final byte SLEEPMODE = 0x10; - private static final byte MODE2MASK = 0x25; - private static final byte BLINKINGOFF = (byte) 0xaa; - private static final byte BLINKINGON = (byte) 0xff; - - - private byte[] buf = new byte[4]; - - protected void init() - { - setRegister(MODE1, MODE1MASK); - setRegister(MODE2, MODE2MASK); - setRegister(LEDOUT, BLINKINGOFF); - setColor(0, 0, 0); - setExternalLED(0); - setRegister(GRPPWM, 0xff); - setRegister(GRPFREQ, 0); - - } - - protected LED(I2CPort port, int address) { - super(port, address); - init(); - } - - protected LED(Port port, int address) { - super(port, address); - init(); - } - - public void disable() { - setRegister(MODE1, MODE1MASK + SLEEPMODE); - } - - public void enable() { - setRegister(MODE1, MODE1MASK); - } - - /** - * Wrapper for sendData that cast register value to byte - * - * @param n - * @param v - */ - private void setRegister(int n, int v) { - buf[0] = (byte) v; - sendData(n, buf, 1); - } - - public void setColor(int r, int g, int b) { - buf[0] = (byte) (r % 256); - buf[1] = (byte) (g % 256); - buf[2] = (byte) (b % 256); - sendData(COLOR + AUTOINCREMENT, buf, 3); - } - - public void setColor(int[] rgb) { - for (int i=0;i<3;i++) - buf[i] = (byte) (rgb[i] % 256); - sendData(COLOR + AUTOINCREMENT, buf, 3); - } - - - public void setHSLColor(int hue, int saturation, int luminosity) { - float _hue = (hue % 360) / 360f; - float _saturation = (saturation % 101) / 100f; - float _luminosity = (luminosity % 101) / 100f; - double v; - double r, g, b; - - r = _luminosity; // default to gray - g = _luminosity; - b = _luminosity; - v = (_luminosity <= 0.5) ? (_luminosity * (1.0 + _saturation)) : (_luminosity + _saturation - _luminosity * _saturation); - if (v > 0) { - double m; - double sv; - int sextant; - double fract, vsf, mid1, mid2; - - m = _luminosity + _luminosity - v; - sv = (v - m) / v; - _hue *= 6.0; - sextant = (int) _hue; - fract = _hue - (double) sextant; - vsf = v * sv * fract; - mid1 = m + vsf; - mid2 = v - vsf; - switch (sextant) { - case 0: - r = v; - g = mid1; - b = m; - break; - case 1: - r = mid2; - g = v; - b = m; - break; - case 2: - r = m; - g = v; - b = mid1; - break; - case 3: - r = m; - g = mid2; - b = v; - break; - case 4: - r = mid1; - g = m; - b = v; - break; - case 5: - r = v; - g = m; - b = mid2; - break; - } - } - setColor((int) (r * 255), (int) (g * 255), (int) (b * 255)); - } - - public void setExternalLED(int w) { - buf[0] = (byte) (w); - sendData(EXTERNAL, buf, 1); - } - - public void setBlinkingPattern(float seconds, int percentageOn) { - int gdc = (int) ((255.0 * percentageOn) / 100.0); - int gfrq = (int) (seconds * 24 - 1); - buf[0] = (byte) gdc; - buf[1] = (byte) gfrq; - sendData(GRPPWM + AUTOINCREMENT, buf, 2); - } - - public void enableBlinking() { - setRegister(LEDOUT, BLINKINGON); - } - - public void disableBlinking() { - setRegister(LEDOUT, BLINKINGOFF); - } - - public int getExternalLED() { - getData(EXTERNAL, buf, 1); - return buf[0]; - } - - public void getColor(int[] rgb) { - getData(COLOR, buf, 3); - for (int i = 0; i < 3; i++) - rgb[i] = buf[i]; - } - - public boolean isEnabled() { - getData(MODE1,buf,1); - if (buf[0]==MODE1MASK) return true; - return false; - } - - public boolean isBlinkingEnabled() { - getData(LEDOUT,buf,1); - if (buf[0]==BLINKINGON) return true; - return false; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/DeviceIdentifier.java b/ev3classes/src/main/java/lejos/hardware/device/DeviceIdentifier.java deleted file mode 100644 index a02890c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/DeviceIdentifier.java +++ /dev/null @@ -1,308 +0,0 @@ -package lejos.hardware.device; - -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.List; - -import lejos.hardware.Device; -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.ConfigurationPort; -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.hardware.sensor.EV3SensorConstants; -import lejos.hardware.sensor.I2CSensor; -import lejos.utility.Delay; - -public class DeviceIdentifier extends Device implements EV3SensorConstants -{ - protected final static int ANALOG_ID_VAR = 50; - protected final static long VALID_TIME = 2000; - protected final static long MIN_TIME = 100; - protected long openTime; - protected Port port; - protected ConfigurationPort configPort; - protected static List> EV3AnalogMap = new ArrayList>(); - static - { - EV3AnalogMap.add(new AbstractMap.SimpleEntry(417, "EV3_TOUCH")); - } - - - /** - * Create an instance of the device identifier for a particular port - * @param port The port to operate with - */ - public DeviceIdentifier(Port port) - { - this.port = port; - openConfigPort(); - } - - public void close() - { - if (configPort != null) - configPort.close(); - super.close(); - } - - protected void openConfigPort() - { - configPort = port.open(ConfigurationPort.class); - openTime = System.currentTimeMillis(); - } - - /** - * Wait until the identification data for this port is valid - */ - protected void waitValid() - { - if (configPort == null) - openConfigPort(); - long minDelay = (openTime + MIN_TIME) - System.currentTimeMillis(); - if (minDelay > 0) - Delay.msDelay(minDelay); - // allow time for detection to work - while (System.currentTimeMillis() < openTime + VALID_TIME) - { - if (configPort.getPortType() != CONN_NONE) - { - //System.out.println("detected after " + i); - break; - } - Delay.msDelay(1); - } - - } - - /** - * Get the type classification for the port. If a sensor is attached to the port - * this will identify the connection type (CONN_NONE, CONN_INPUT_UART etc.). See - * the class EV3SensorConstants for the actual values - * @return The type of the port - * - */ - public int getPortType() - { - waitValid(); - return configPort.getPortType(); - } - - /** - * This method returns information on the sensor/motor that is attached to the - * specified port. Note that only very basic sensor identification information - * may be available for some sensor types. It may be necessary to actually open the - * sensor to allow it to be identified in further detail. - * @return the sensor type - */ - public int getDeviceType() - { - waitValid(); - return configPort.getDeviceType(); - } - - /** - * Returns the signature for a dumb NXT sensor - * @return string identifying the device - */ - protected String getNXTDumbSignature() - { - switch(getDeviceType()) - { - case TYPE_NXT_TOUCH: - return "NXT_TOUCH"; - case TYPE_NXT_LIGHT: - return "NXT_LIGHT"; - case TYPE_NXT_SOUND: - return "NXT_SOUND"; - default: - return "UNKNOWN"; - } - } - - /** - * Returns the signature for a i2c sensor - * @return string identifying the device - */ - protected String getI2CSignature(boolean full) - { - configPort.close(); - configPort = null; - String product = ""; - String vendor = ""; - String version = ""; - String address = ""; - I2CSensor i2c = null; - try { - // we need to try and read the device identification strings - i2c = new I2CSensor(port); - // search for the device on available addresses - for(int i = 2; i < 255; i+= 2) - { - i2c.setAddress(i); - product = i2c.getProductID(); - if (product.length() != 0) - { - if (i > 2) - address = String.valueOf(i); - break; - } - } - vendor = i2c.getVendorID(); - version = i2c.getVersion(); - } - catch (Exception e) - { - // ignore any exceptions during detection. - } - finally - { - if (i2c != null) - i2c.close(); - openConfigPort(); - } - if (product.length() == 0) - product = "unknown"; - if (vendor.length() == 0) - vendor = "unknown"; - if (version.length() == 0) - version = "unknown"; - if (address.length() != 0) - address = "//" + address + "/"; - String ret = address + vendor + "/" + product; - if (full) - ret += "/" + version; - return ret; - } - - /** - * Returns the signature for a dumb EV3 sensor - * @return string identifying the device - */ - protected String getEV3DumbSignature() - { - // need to look at analog value on pin 1 to identify - configPort.close(); - configPort = null; - String product = ""; - AnalogPort ap = null; - try { - ap = port.open(AnalogPort.class); - int p1mV = (int)(ap.getPin1()*1000); - System.out.println("Pin 1 voltage is " + p1mV); - // search for a matching sensor - for(AbstractMap.SimpleEntry sensor : EV3AnalogMap) - { - int key = sensor.getKey(); - if ((key - ANALOG_ID_VAR) < p1mV && (key + ANALOG_ID_VAR ) > p1mV) - { - product = sensor.getValue(); - break; - } - } - } - catch (Exception e) - { - // ignore any exceptions during detection. - } - finally - { - if (ap != null) - ap.close(); - openConfigPort(); - } - if (product.length() == 0) - product = "unknown"; - return product; - } - - /** - * Returns the signature for a UART sensor - * @return string identifying the device - */ - protected String getUARTSignature() - { - configPort.close(); - configPort = null; - String product = ""; - UARTPort uart = null; - try { - // we need to try and read the device identification strings - uart = port.open(UARTPort.class); - uart.setMode(0); - product = uart.getModeName(0); - } - catch (Exception e) - { - // ignore any exceptions during detection. - } - finally - { - if (uart != null) - uart.close(); - openConfigPort(); - } - if (product.length() == 0) - product = "unknown"; - return product; - } - - /** - * Returns the signature for a motor/output device - * @return string identifying the device - */ - protected String getMotorSignature() - { - switch(getDeviceType()) - { - case TYPE_TACHO: - return "TACHO"; - case TYPE_MINITACHO: - return "MINITACHO"; - case TYPE_NEWTACHO: - return "NEWTACHO"; - default: - return "UNKNOWN"; - } - } - - - /** - * return the signature of the attached device. This signature can be used to identify - * the actual device. Note that identification may require that the device is opened. - * @param full true to return all available information, false for basic information - * @return a string signature - */ - public String getDeviceSignature(boolean full) - { - int portType = getPortType(); - switch(portType) - { - case CONN_NONE: - return "NONE:NONE"; - case CONN_ERROR: - case CONN_UNKNOWN: - return "UNKNOWN:UNKNOWN"; - case CONN_NXT_COLOR: - return "NXT_COLOR:NXT_COLOR"; - case CONN_NXT_DUMB: - return "NXT_ANALOG:" + getNXTDumbSignature(); - case CONN_NXT_IIC: - return "IIC:" + getI2CSignature(full); - case CONN_INPUT_DUMB: - return "EV3_ANALOG:" + getEV3DumbSignature(); - case CONN_INPUT_UART: - return "UART:" + getUARTSignature(); - case CONN_OUTPUT_DUMB: - // TODO: Does anyone have anything that is recognised as this? - return "OUTPUT_DUMB:UNKNOWN"; - case CONN_OUTPUT_INTELLIGENT: - // TODO: Same for this type - return "OUTPUT_INTELLIGENT:UNKNOWN"; - case CONN_OUTPUT_TACHO: - return "OUTPUT_TACHO:" + getMotorSignature(); - default: - return "UNKNOWN:UNKNOWN"; - } - } - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/device/IRLink.java b/ev3classes/src/main/java/lejos/hardware/device/IRLink.java deleted file mode 100644 index bc12b7f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/IRLink.java +++ /dev/null @@ -1,225 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; -import lejos.remote.rcx.Opcode; - -import java.util.*; - -/** - * Supports for HiTechnic NXT IRLink Sensor (NIL1046) IRLink. - * - * @author Lawrie Griffiths - * - */ -public class IRLink extends I2CSensor implements Opcode, IRTransmitter { - - /* - * Documentation: http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NIL1046 - * - * ProductId: "HiTechnc" - * SensorType: "IRLink" - * (confirmed for version " V1.2") - */ - - //Registers - private final static byte TX_BUFFER = 0x40; // 40 to 4C - private final static byte TX_BUFFER_LEN = 0x4D; - private final static byte TX_MODE = 0x4E; - private final static byte TX_BUFFER_FLAG = 0x4F; - - private final static byte TX_MAX_BUFFER_LEN = 13; - - // IRLink transmission modes - private final static byte TX_MODE_RCX = 0; - private final static byte TX_MODE_TRAIN = 1; - private final static byte TX_MODE_PF = 2; - - // PF Modes - public final static byte PF_MODE_COMBO_DIRECT = 1; - - // IR PF signal encoding parameters - private final byte MAX_BITS = TX_MAX_BUFFER_LEN * 8; - private final byte STOP_START_PAUSE = 7; - private final byte LOW_BIT_PAUSE = 2; - private final byte HIGH_BIT_PAUSE = 4; - - // PF motor operations - public static final byte PF_FLOAT = 0; - public static final byte PF_FORWARD = 1; - public static final byte PF_BACKWARD = 2; - public static final byte PF_BRAKE = 3; - - // RCX Remote operation code - public static int RCX_REMOTE_BEEP = 0x8000; - public static int RCX_REMOTE_STOP = 0x4000; - public static int RCX_REMOTE_P5 = 0x2000; - public static int RCX_REMOTE_P4 = 0x1000; - public static int RCX_REMOTE_P3 = 0x0800; - public static int RCX_REMOTE_P2 = 0x0400; - public static int RCX_REMOTE_P1 = 0x0200; - public static int RCX_REMOTE_C_BWD = 0x0100; - public static int RCX_REMOTE_B_BWD = 0x0080; - public static int RCX_REMOTE_A_BWD = 0x0040; - public static int RCX_REMOTE_C_FWD = 0x0020; - public static int RCX_REMOTE_B_FWD = 0x0010; - public static int RCX_REMOTE_A_FWD = 0x0008; - public static int RCX_REMOTE_MSG3 = 0x0004; - public static int RCX_REMOTE_MSG2 = 0x0002; - public static int RCX_REMOTE_MSG1 = 0x0001; - - private byte toggle = 0; - - private BitSet bits = new BitSet(MAX_BITS); - private int nextBit = 0; - - public IRLink(I2CPort port) { - super(port); - } - - public IRLink(Port port) { - super(port); - } - - /** - * Send commands to both motors. - * Uses PF Combo direct mode. - * - * @param channel the channel number (0-3) - * @param opA Motor A operation - * @param opB Motor B operation - */ - public void sendPFComboDirect(int channel, int opA, int opB) { - sendPFCommand(channel, PF_MODE_COMBO_DIRECT, opB << 2 | opA); - } - - private void sendPFCommand(int channel, int mode, int data) { - byte nibble1 = (byte) ((toggle << 3) | channel); - byte lrc = (byte) (0xF ^ nibble1 ^ mode ^ data); - int pfData = (nibble1 << 12) | (mode << 8) | (data << 4) | lrc; - - clearBits(); - nextBit = 0; - setBit(STOP_START_PAUSE); // Start - for(int i=15;i>=0;i--) { - setBit(((pfData >> i) & 1) == 0 ? LOW_BIT_PAUSE : HIGH_BIT_PAUSE); - } - setBit(STOP_START_PAUSE); // Stop - toggle ^= 1; - byte [] pfCommand = new byte[16]; - - for(int i =0;i> 8); - buf[2] = (byte) (msg & 0xFF); - sendPacket(buf); - } - - public void runProgram(int programNumber) { - sendRemoteCommand(RCX_REMOTE_P1 << (programNumber -1)); - } - - public void beep() { - sendRemoteCommand(RCX_REMOTE_BEEP); - } - - public void stopAllPrograms() { - sendRemoteCommand(RCX_REMOTE_STOP); - } - - public void forwardStep(int motor) { - sendRemoteCommand(RCX_REMOTE_A_FWD << motor); - } - - public void backwardStep(int motor) { - sendRemoteCommand(RCX_REMOTE_A_BWD << motor); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/IRTransmitter.java b/ev3classes/src/main/java/lejos/hardware/device/IRTransmitter.java deleted file mode 100644 index 3dd7fd3..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/IRTransmitter.java +++ /dev/null @@ -1,40 +0,0 @@ -package lejos.hardware.device; - -/** - * Interface for infra-red transmitters that can send bytes to an RCX - * - * @author Lawrie Griffiths - */ -public interface IRTransmitter { - - /** - * Send raw bytes to the RCX - * @param data the raw data - * @param len the number of bytes - */ - public void sendBytes(byte [] data, int len); - - /** - * Send a packet of data to the RCX - * @param packet - */ - public void sendPacket(byte[] packet); - - /** - * Send a remote control command to the RCX - * - * @param msg the code for the remote command - */ - public void sendRemoteCommand(int msg); - - public void runProgram(int programNumber); - - public void forwardStep(int motor); - - public void backwardStep(int motor); - - public void beep(); - - public void stopAllPrograms(); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/LDCMotor.java b/ev3classes/src/main/java/lejos/hardware/device/LDCMotor.java deleted file mode 100644 index 1308928..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/LDCMotor.java +++ /dev/null @@ -1,78 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; - -/** - * LDCMotor, Lattebox DC Motor, is a abstraction to model any DCMotor connected to - * LSC, Lattebox Servo Controller. - * - * @author Juan Antonio Brenha Moral - * - */ -public class LDCMotor extends LMotor{ - - private int speed; - private int forward_min_speed = 1020; - private int forward_max_speed = 850; - private int backward_min_speed = 1080; - private int backward_max_speed = 1230; - - /** - * Constructor - * - * @param port - * @param location - * @param DCMotorName - * @param SPI_PORT - * - */ - public LDCMotor(I2CPort port, int location, String DCMotorName, byte SPI_PORT){ - super(port,location,DCMotorName,SPI_PORT); - } - - public LDCMotor(I2CPort port, int location, String DCMotorName, byte SPI_PORT,int forwardMinSpeed,int forwardMaxSpeed,int backwardMinSpeed, int backwardMaxSpeed){ - super(port,location,DCMotorName,SPI_PORT); - - this.forward_min_speed = forwardMinSpeed; - this.forward_max_speed = forwardMaxSpeed; - this.backward_min_speed = backwardMinSpeed; - this.backward_max_speed = backwardMaxSpeed; - } - - /** - * Method to set the speed in a DC Motor - * - * @param speed the speed - * - */ - public void setSpeed(int speed){ - this.setPulse(speed); - } - - /** - * - * Method to get speed from the DC Motor - * - * @return the speed - * - */ - public int getSpeed(){ - return this.getPulse(); - } - - public void setForwardMinSpeed(int min_speed){ - this.forward_min_speed = min_speed; - } - - public void setForwardMaxSpeed(int max_speed){ - this.forward_max_speed = max_speed; - } - - public void setBackwardMinSpeed(int min_speed){ - this.backward_min_speed = min_speed; - } - - public void setBackwardMaxSpeed(int max_speed){ - this.backward_max_speed = max_speed; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/LMotor.java b/ev3classes/src/main/java/lejos/hardware/device/LMotor.java deleted file mode 100644 index a812aec..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/LMotor.java +++ /dev/null @@ -1,226 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.port.SensorPort; -import lejos.hardware.sensor.I2CSensor; - -/** - * Generic abstraction to manage RC Servos and DC Motor. - * LServo and LDCMotor uses inherits from this class - * - * @author Juan Antonio Brenha Moral - * - */ -public class LMotor extends I2CSensor{ - private String name = "";//String to describe any Motor connected to LSC - protected int LSC_position; //Position where Servo has been plugged - - //Servo ID - private SensorPort portConnected;//What - protected byte SPI_PORT;//What SPI Port is connected LSC - - public static final int arrMotorUnload[] = {0x01,0x02,0x04,0x08,0x20,0x40,0x80,0x100,0x200}; - public static final int arrMotorLoad[] = {0x3FE,0x3FD,0x3FB,0x3F7,0x3EF,0x3DF,0x3BF,0x37F,0x2FF,0x1FF}; - - /** - * Constructor - * - * @param port the port - * @param location the location - * @param name the name of the servo - * @param SPI_PORT the SPI port - * - */ - public LMotor(I2CPort port, int location, String name, byte SPI_PORT){ - super(port, NXTe.NXTE_ADDRESS); - this.name = name; - this.LSC_position = location; - - this.SPI_PORT = SPI_PORT; - } - - /** - * Constructor - * - * @param port the port - * @param location the location - * @param name the name of the servo - * @param SPI_PORT the SPI port - * - */ - public LMotor(Port port, int location, String name, byte SPI_PORT){ - super(port, NXTe.NXTE_ADDRESS); - this.name = name; - this.LSC_position = location; - - this.SPI_PORT = SPI_PORT; - } - - /** - * - * private method to know internal information about - * if the servo is moving - * - * @return - * - */ - private int readMotion(){ - byte[] bufReadResponse; - bufReadResponse = new byte[8]; - byte h_byte; - byte l_byte; - - int motion = -1; - - //Write OP Code - sendData((int)this.SPI_PORT, (byte)0x68); - - //Read High Byte - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - h_byte = bufReadResponse[0]; - - //Read Low Byte - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - l_byte = bufReadResponse[0]; - - if(l_byte == 0xFF){ - motion = ((h_byte & 0x07 ) << 8) + 255; - }else{ - motion = ((h_byte & 0x07 ) << 8)|(l_byte&0xFF); - } - return motion; - } - - /** - * Method to know if Servo is moving to a determinated angle - * - * @return true iff the servo is moving - */ - public boolean isMoving(){ - boolean flag = false; - if(readMotion() != 0){ - flag = true; - } - return flag; - } - - /** - * Set a delay in a Motor - * - * @param delay the delay - */ - public void setDelay(int delay){ - byte h_byte; - byte l_byte; - - int motor = LSC_position; - h_byte = (byte)0xF0; - l_byte = (byte)(((motor)<<4) + delay); - - sendData((int)this.SPI_PORT, h_byte); - sendData((int)this.SPI_PORT, l_byte); - } - - public void unload(){ - byte[] bufReadResponse; - byte h_byte; - byte l_byte; - - int channel = 0x00; - channel = arrMotorUnload[LSC_position]; - - h_byte = (byte)0xe0; //0xe0 | (0x00 >>(byte)8); //?? - l_byte = (byte)channel; - - //High Byte Write - sendData((int)this.SPI_PORT, h_byte); - - //Low Byte Write - sendData((int)this.SPI_PORT, l_byte); - } - - /** - * Load Servo located in a position X - * - */ - public void load(){ - byte h_byte; - byte l_byte; - - int channel = 0x00; - channel = arrMotorLoad[LSC_position]; - - h_byte = (byte)0xe0; //0xe0 | (0x00 >>(byte)8); //?? - l_byte = (byte)channel; - - //High Byte Write - sendData((int)this.SPI_PORT, h_byte); - - //Low Byte Write - sendData((int)this.SPI_PORT, l_byte); - } - - /** - * Get name from a RC Servo or a DC Motor - * - */ - public String getName(){ - return this.name; - } - - /** - * This class set the Pulse over a RC Servo or a DC Motor - * - * @param pulse - */ - protected void setPulse(int pulse){ - byte h_byte; - byte l_byte; - - int servo = LSC_position; - h_byte = (byte)(0x80 | ((servo<<3) | (pulse >>8))); - l_byte = (byte)pulse; - - //High Byte Write - sendData((int)this.SPI_PORT, h_byte); - - //Low Byte Write - sendData((int)this.SPI_PORT, l_byte); - } - - /** - * This method return current pulse over a RC Servo or a DC Motor. - * This method is used internally by LDCMotor Objects or LServo Objects - * to get the speed or angle. - * - * @return the pulse - */ - protected int getPulse(){ - byte[] bufReadResponse; - bufReadResponse = new byte[8]; - byte h_byte; - byte l_byte; - - int servo = LSC_position; - //Write OP Code - h_byte = (byte)(servo << 3); - sendData((int)this.SPI_PORT, h_byte); - - //Read High Byte - //I2CBytes(IN_3, bufReadValue, buflen, bufReadResponse); - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - - h_byte = bufReadResponse[0]; - - //Read Low Byte - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - l_byte = bufReadResponse[0]; - - return ((h_byte & 0x07 ) << 8) + (l_byte & 0x00000000FF); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/LSC.java b/ev3classes/src/main/java/lejos/hardware/device/LSC.java deleted file mode 100644 index 0aba860..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/LSC.java +++ /dev/null @@ -1,226 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -import java.util.ArrayList; - -/** - * This class has been defined to manage the device - * LSC, Lattebox Servo Controller which - * manage until 10 RC Servos / DC Motors - * - * @author Juan Antonio Brenha Moral - * - */ - -public class LSC extends I2CSensor { - - //Servo Management - private ArrayList arrServo;//ServoController manage until 10 RC Servos - private ArrayList arrDCMotor;//ServoController manage until 10 DC Motors - private final int MAXIMUM_SERVOS_DCMOTORS = 10;//LSC Suports until 10 RC Servos - - //Exception handling - private final String ERROR_SERVO_DEFINITION = "Error with Servo definition"; - private final String ERROR_SERVO_LOCATION = "Error with Servo location"; - - //I2C - private byte SPI_PORT; - private I2CPort portConnected; - - /** - * - * Constructor - * - * @param port - * @param SPI_PORT - * - */ - public LSC(I2CPort port,byte SPI_PORT){ - super(port, NXTe.NXTE_ADDRESS); - this.portConnected = port; - this.SPI_PORT = SPI_PORT; - - arrServo = new ArrayList(); - arrDCMotor = new ArrayList(); - - } - - /** - * - * Constructor - * - * @param port - * @param SPI_PORT - * - */ - public LSC(Port port,byte SPI_PORT){ - super(port, NXTe.NXTE_ADDRESS); - this.portConnected = this.port; - this.SPI_PORT = SPI_PORT; - - arrServo = new ArrayList(); - arrDCMotor = new ArrayList(); - - } - - /** - * Method to add a RC servo to current LSC - * - * @param location the location - * @param name the name of the servo - * @throws ArrayIndexOutOfBoundsException - * - */ - public void addServo(int location, String name) throws ArrayIndexOutOfBoundsException{ - if(arrServo.size() <=MAXIMUM_SERVOS_DCMOTORS){ - LServo s = new LServo(this.portConnected,location, name,this.SPI_PORT); - arrServo.add(s); - }else{ - //throw new ArrayIndexOutOfBoundsException(ERROR_SERVO_DEFINITION); - throw new ArrayIndexOutOfBoundsException(); - } - } - - /** - * Method to add a RC servo to current LSC - * - * @param location the location - * @param name the name of the servo - * @throws ArrayIndexOutOfBoundsException - * - */ - public void addServo(int location, String name,int min_angle, int max_angle) throws ArrayIndexOutOfBoundsException{ - if(arrServo.size() <=MAXIMUM_SERVOS_DCMOTORS){ - LServo s = new LServo(this.portConnected,location, name,this.SPI_PORT,min_angle,max_angle); - arrServo.add(s); - }else{ - //throw new ArrayIndexOutOfBoundsException(ERROR_SERVO_DEFINITION); - throw new ArrayIndexOutOfBoundsException(); - } - } - - /** - * Method to get an RC Servo in a LSC - * - * @param index in the array - * @return the LServo object - * - */ - public LServo getServo(int index){ - return this.arrServo.get(index); - } - - /** - * Method to add a DC Motor - * - * @param location the location - * @param name the name of the motor - * - */ - public void addDCMotor(int location, String name) throws ArrayIndexOutOfBoundsException{ - if(arrDCMotor.size() <=MAXIMUM_SERVOS_DCMOTORS){ - LDCMotor dcm = new LDCMotor(this.portConnected,location, name,this.SPI_PORT); - arrDCMotor.add(dcm); - }else{ - //throw new ArrayIndexOutOfBoundsException(ERROR_SERVO_DEFINITION); - throw new ArrayIndexOutOfBoundsException(); - } - } - - /** - * Method to add a DC Motor - * - * @param location - * @param name - * - */ - public void addDCMotor(int location, String name,int forward_min_speed,int forward_max_speed,int backward_min_speed,int backward_max_speed) throws ArrayIndexOutOfBoundsException{ - if(arrDCMotor.size() <=MAXIMUM_SERVOS_DCMOTORS){ - LDCMotor dcm = new LDCMotor(this.portConnected,location, name,this.SPI_PORT,forward_min_speed,forward_max_speed,backward_min_speed,backward_max_speed); - arrDCMotor.add(dcm); - }else{ - //throw new ArrayIndexOutOfBoundsException(ERROR_SERVO_DEFINITION); - throw new ArrayIndexOutOfBoundsException(); - } - } - - /** - * Method to get an LDC Motor - * - * @param index the index in the array - * @return the LDC Motor - * - */ - public LDCMotor getDCMotor(int index){ - return this.arrDCMotor.get(index); - } - - //I2C Methods - - /** - * This method check LSC connected with NXTe - * Currently I am debugging - * - */ - public void calibrate(){ - byte[] bufReadResponse; - bufReadResponse = new byte[8]; - byte h_byte; - byte l_byte; - - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - - while(bufReadResponse[0] != 99){ - sendData((int)this.SPI_PORT, (byte)0xFF); - sendData((int)this.SPI_PORT, (byte)0xFF); - sendData((int)this.SPI_PORT, (byte)0x7E); - - sendData((int)this.SPI_PORT, (byte)0x00); - getData((int)this.SPI_PORT, bufReadResponse, 1); - - if((int)bufReadResponse[0] == 99){ - break; - } - } - } - - /** - * Load all servos connected this this LSC - */ - public void loadAllServos(){ - byte h_byte; - byte l_byte; - - int channel = 1023; - h_byte = (byte)0xe0; //0xe0 | (0x00 >>(byte)8); //?? - l_byte = (byte)channel; - - //High Byte Write - sendData((int)this.SPI_PORT, h_byte); - - //Low Byte Write - sendData((int)this.SPI_PORT, l_byte); - } - - /** - * Unload all servos connected in a LSC - */ - public void unloadAllServos(){ - byte h_byte; - byte l_byte; - - int channel = 0x00; - h_byte = (byte)0xe0; //0xe0 | (0x00 >>(byte)8); //?? - l_byte = (byte)channel; - - //High Byte Write - sendData((int)this.SPI_PORT, h_byte); - - //Low Byte Write - sendData((int)this.SPI_PORT, l_byte); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/LServo.java b/ev3classes/src/main/java/lejos/hardware/device/LServo.java deleted file mode 100644 index a106d75..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/LServo.java +++ /dev/null @@ -1,160 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; - -/** - * LServo, Lattebox Servo, is a abstraction to model any RC Servo (continous and non continous) plugged to - * LSC, Lattebox Servo Controller. - * - * @author Juan Antonio Brenha Moral - * - */ -public class LServo extends LMotor{ - private int min_angle = 0; - private int max_angle = 2000; - private int init_angle = 1000; - - /** - * Constructor - * - * @param port - * @param location - * @param servoName - * @param SPI_PORT - * - */ - public LServo(I2CPort port, int location, String servoName, byte SPI_PORT){ - super(port,location,servoName,SPI_PORT); - } - - /** - * - * Constructor with the feature to set min and max angle - * - * @param port - * @param location - * @param servoName - * @param SPI_PORT - * @param min_angle - * @param max_angle - * - */ - public LServo(I2CPort port, int location, String servoName, byte SPI_PORT,int min_angle, int max_angle){ - super(port,location,servoName,SPI_PORT); - - this.min_angle = min_angle; - this.max_angle = max_angle; - } - - /** - * - * Constructor with the feature to set min, max and init angle - * - * @param port - * @param location - * @param servoName - * @param SPI_PORT - * @param min_angle - * @param max_angle - * @param init_angle - * - */ - public LServo(I2CPort port, int location, String servoName, byte SPI_PORT,int min_angle, int max_angle,int init_angle){ - super(port,location,servoName,SPI_PORT); - - this.min_angle = min_angle; - this.max_angle = max_angle; - this.init_angle = init_angle; - } - - /** - * Method to set an Angle in a RC Servo. - * - * @param angle - * - */ - public void setAngle(int angle){ - this.setPulse(angle); - } - - /** - * - * Method to know the angle - * - * @return the angle - * - */ - public int getAngle(){ - return this.getPulse(); - } - - /** - * Set Minimal angle. Useful method to calibrate a Servo - * - * @param minAngle the minimum angle - * - */ - public void setMinAngle(int minAngle){ - this.min_angle = minAngle; - } - - /** - * Set Maximum angle. Useful method to calibrate a Servo - * - * @param maxAngle - * - */ - public void setMaxAngle(int maxAngle){ - this.max_angle = maxAngle; - } - - /** - * Method to set minimal angle - * - */ - public void goToMinAngle(){ - this.setAngle(this.min_angle); - } - - /** - * Method to set maximum angle - * - */ - public void goToMaxAngle(){ - this.setAngle(this.max_angle); - } - - /** - * Method to set medium angle - * - */ - public void goToMiddleAngle(){ - float middle = (this.min_angle + this.max_angle) / 2; - - this.setAngle(Math.round(middle)); - } - - /** - * Method to set medium angle - * - */ - public void goToInitAngle(){ - this.setAngle(this.init_angle); - } - - /** - * Classic forward method for continous RC Servos - * - */ - public void forward(){ - this.setAngle(0); - } - - /** - * Classic backward method for continous RC Servos - * - */ - public void backward(){ - this.setAngle(2000); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/LnrActrFirgelliNXT.java b/ev3classes/src/main/java/lejos/hardware/device/LnrActrFirgelliNXT.java deleted file mode 100644 index 2710031..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/LnrActrFirgelliNXT.java +++ /dev/null @@ -1,358 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.motor.UnregulatedMotor; -import lejos.hardware.port.Port; -import lejos.robotics.EncoderMotor; -import lejos.robotics.LinearActuator; - -/** A Linear Actuator class that provides blocking and non-blocking move actions with stall detection. Developed for the - * Firgelli L12-NXT-50 and L12-NXT-100 - * but may work for others. These linear actuators are self contained units which include an electric motor and encoder. They will push - * up to 25N and move at up to 12 mm/sec unloaded. - *

- * This class in not thread-safe and it is up to the caller to properly handle synchronization when calling its methods in a - * multithreaded software implementation. - *

- * This is not an endorsement: For informational purposes, see www.firgelli.com. for details on the actuators. - * @author Kirk P. Thompson - * - */ -public class LnrActrFirgelliNXT implements LinearActuator{ -// private static final int MIN_POWER = 30; - - private EncoderMotor encoderMotor; - private volatile int motorPower =0; - private volatile int tick_wait; // this is calculated in setPower() to fit the power setting. Variable because lower powers move it slower. - private volatile boolean isMoveCommand = false; - private volatile boolean isStalled=false; - private Thread actuator; - private volatile boolean dirExtend = true; - private volatile int distanceTicks; - private volatile boolean killCurrentAction=false; - private Object synchObj1 = new Object(); - private volatile int tachoCount=0; - - /**Create a LnrActrFirgelliNXT instance. - * Use this constructor to assign an instance of EncoderMotor used to drive the actuater motor. This constructor - * allows any motor class that implements the EncoderMotor interface to drive the actuator. You must instantiate - * the EncoderMotor-type motor before passing it to this constructor. - *

- * When an instance of the MMXMotor class is used, the motor power curve is much different that with a NXTMotor (due to - * a different PWM output?) . The speed - * peaks out at about 20% power so in effect, the speed control granularity is coarser. - *

- * The default power at instantiation is 100%. - * @param encoderMotor A motor instance of type EncoderMotor which will drive the actuator - * @see lejos.hardware.motor.UnregulatedMotor - * @see MMXMotor - * @see EncoderMotor - */ - public LnrActrFirgelliNXT(EncoderMotor encoderMotor) { - this.encoderMotor=encoderMotor; - this.encoderMotor.flt(); - - setPower(100); - this.actuator = new Thread(new Actuator()); - this.actuator.setDaemon(true); - this.actuator.start(); - doWait(100); - } - - /** Convenience constructor that creates an instance of a NXTMotor using the specified motor port. This instance is then - * used to drive the actuator motor. - *

- * The default power at instantiation is 100%. - * @param port The motor port that the linear actuator is attached to. - * @see lejos.hardware.port.MotorPort - * @see UnregulatedMotor - */ - public LnrActrFirgelliNXT(Port port) { - this(new UnregulatedMotor(port)); - } - - /**Sets the power for the actuator. This is called before the move() or moveTo() method is called - * to set the power. - * Using lower power values and pushing/pulling - * an excessive load may cause a stall and in this case, stall detection will stop the current actuator action and - * set the stalled condition flag. - *

- * The default power value on instantiation is 100%. - * @param power power setting: 0-100% - * @see LinearActuator#move(int,boolean) - * @see #isStalled - */ - public void setPower(int power){ - power=Math.abs(power); - this.motorPower = (power>100)?100:power; - this.encoderMotor.setPower(this.motorPower); - - // calc encoder tick/ms based on my testing. y=mm/sec, x=power + 10% - if (this.encoderMotor instanceof MMXMotor) { - this.tick_wait = (int)(500/(0.4396f * this.motorPower + 3.8962f)); - } else { - this.tick_wait = (int)(500/(0.116f * this.motorPower - 0.5605f)) ; - } - - // ~12 mm/s = ~40 ms/encoder tick - if (this.tick_wait<40) this.tick_wait = 40; - // ~2.5 mm/s = ~200 ms/encoder tick - if (this.tick_wait>200) this.tick_wait = 200; - // add 10% for unit manufacturing tolerance variance - this.tick_wait = (int)(this.tick_wait * 1.1f); - } - - /** - * Returns the current actuator motor power setting. - * @return current power 0-100% - */ - public int getPower() { - return this.motorPower; - } - - /**Returns true if the actuator is in motion. - * @return true if the actuator is in motion. - */ - public boolean isMoving() { - return this.isMoveCommand; - } - - /**Returns true if a move() or moveTo() order ended due to a motor stall. This behaves - * like a latch where the - * reset of the stall status is done on a new move() or moveTo() order. - * @return true if actuator motor stalled during a movement order. false otherwise. - * @see LinearActuator#move(int,boolean) - */ - public boolean isStalled() { - return this.isStalled; - } - - - /**Causes the actuator to move distance in encoder ticks. The distance is relative to the actuator - * shaft position at the time of calling this method. - * Positive values extend the actuator shaft while negative values retract it. - * The Firgelli L12-NXT-50 & 100 use 0.5 mm/encoder tick. eg: 200 ticks=100 mm. - *

- * Stall detection stops the actuator in the event of a stall condition to help prevent damage to the actuator. - *

- * If immediateReturn is true, this method returns immediately (does not block) and the actuator stops when the - * stroke distance is met [or a stall is detected]. If another move action is called before the - * stroke - * distance is reached, the current actuator action is cancelled and the new action is initiated. - *

- * If the stroke distance specified exceeds the maximum - * stroke length (fully extended or retracted against an end stop), stall detection will stop the action. It is advisable - * not to extend or retract to the - * stop as this is hard on the actuator. If you must go all the way to an end stop and rely on stall detection to stop the - * action, use a lower power setting. - * - * @param distance The Stroke distance in encoder ticks. - * @param immediateReturn Set to true to cause the method to immediately return while the action is executed in - * the background. - * false will block until the action is completed, whether successfully or stalled. - * @see #setPower - * @see #stop - * @see #getTachoCount - * @see #moveTo(int,boolean) - */ - public synchronized void move(int distance, boolean immediateReturn ){ - // set globals - this.dirExtend=distance>=0; - this.distanceTicks = Math.abs(distance); - // initiate the action - doAction(immediateReturn); - } - - /**Causes the actuator to move to absolute position in encoder ticks. The position of the actuator - * shaft on startup or when set by resetTachoCount() is zero. - * @param position The absolute shaft position in encoder ticks. - * @param immediateReturn Set to true to cause the method to immediately return while the action is executed in - * the background. - * @see #move(int,boolean) - * @see #resetTachoCount - */ - public void moveTo(int position, boolean immediateReturn ){ - int distance = position - this.tachoCount; - move(distance, immediateReturn); - } - - // only called by move() - private void doAction(boolean immediateReturn){ - // If we already have an active command, signal it to cease and wait until cleared - if (this.isMoveCommand) { - this.killCurrentAction=true; - synchronized(this.synchObj1){ - while (this.isMoveCommand) { - try { - this.synchObj1.wait(); - } catch (InterruptedException e) { - ; //ignore - } - } - } - } - // initiate the action by waking up the actuator thread to do the action - this.killCurrentAction=false; // ensure state baseline - synchronized (this.actuator) { - // set state to indicate an action is in effect - this.isMoveCommand=true; - this.isStalled=false; - this.actuator.notify(); - } - - // if told to block, wait until the actuator thread completes its current task. When done, it will do a notify() to wake - // us up here. - if (!immediateReturn) { - synchronized(this.synchObj1){ - while (!this.killCurrentAction) { - try { - this.synchObj1.wait(); - } catch (InterruptedException e) { - ; // ignore - } - } - } - } - } - - /**This thread does the actuator control - */ - private class Actuator implements Runnable{ - private static final int STALL_COUNT = 3; - - public void run() { - while(true) { - // wait until triggered to do an actuation - synchronized (LnrActrFirgelliNXT.this.actuator) { - while (true){ - try { - LnrActrFirgelliNXT.this.actuator.wait(); - if (LnrActrFirgelliNXT.this.isMoveCommand) break; - } catch (InterruptedException e) { - ; // do nothing and continue - } - } - } - - // this blocks. When finished, toExtent() will reset this.isMoveCommand, etc. w/ call to stop() - toExtent(); - - // wake up any wait in doAction() - synchronized(LnrActrFirgelliNXT.this.synchObj1){ - LnrActrFirgelliNXT.this.synchObj1.notify(); - } - } - } - - // starts the motor and waits until move is completed or interrupted with the this.killCurrentAction - // flag which in effect, causes the thread wait/block until next command is issued (this.isMoveCommand set to true) - private void toExtent() { - int power = LnrActrFirgelliNXT.this.motorPower; - int tacho=0; - int temptacho; - - LnrActrFirgelliNXT.this.encoderMotor.resetTachoCount(); - - // initiate the actuator action - if (LnrActrFirgelliNXT.this.dirExtend) { - LnrActrFirgelliNXT.this.encoderMotor.forward(); - } else { - LnrActrFirgelliNXT.this.encoderMotor.backward(); - } - - // wait until the actuator shaft starts moving (with a time limit) - int begTacho=LnrActrFirgelliNXT.this.encoderMotor.getTachoCount(); - long begTime = System.currentTimeMillis(); - while (!LnrActrFirgelliNXT.this.killCurrentAction&&(begTacho==LnrActrFirgelliNXT.this.encoderMotor.getTachoCount())) { - doWait(LnrActrFirgelliNXT.this.tick_wait/2); - // kill the move and exit if it takes too long to start moving - if ((System.currentTimeMillis()-begTime)>LnrActrFirgelliNXT.this.tick_wait*6) { - LnrActrFirgelliNXT.this.isStalled=true; - LnrActrFirgelliNXT.this.killCurrentAction=true; // will cause loop below to immediately finish - break; - } - } - - // monitor the move and stop when stalled or action completes - begTime = System.currentTimeMillis(); - temptacho=LnrActrFirgelliNXT.this.tachoCount; - while (!LnrActrFirgelliNXT.this.killCurrentAction) { - // Stall check. if no tacho change... - if (begTacho==LnrActrFirgelliNXT.this.encoderMotor.getTachoCount()) { - // ...and we exceed STALL_COUNT wait periods and have been commanded to move, it probably means we have stalled - if (System.currentTimeMillis()- begTime>LnrActrFirgelliNXT.this.tick_wait*STALL_COUNT) { - LnrActrFirgelliNXT.this.isStalled=true; - break; - } - } else { - // The tacho is moving, get the current point and time for next comparision - begTacho=LnrActrFirgelliNXT.this.encoderMotor.getTachoCount(); - begTime = System.currentTimeMillis(); - } - // calc abs tacho - tacho = LnrActrFirgelliNXT.this.encoderMotor.getTachoCount(); - LnrActrFirgelliNXT.this.tachoCount = temptacho - tacho; - tacho=Math.abs(tacho); - - // reduce speed when near destination when at higher speeds - if (LnrActrFirgelliNXT.this.distanceTicks-tacho<=4&&power>80) LnrActrFirgelliNXT.this.encoderMotor.setPower(70); - // exit loop if destination is reached - if (tacho>=LnrActrFirgelliNXT.this.distanceTicks) break; - // if power changed during this run.... (only when immediateReturn=true) - if (power!=LnrActrFirgelliNXT.this.motorPower) { - power = LnrActrFirgelliNXT.this.motorPower; - LnrActrFirgelliNXT.this.encoderMotor.setPower(power); - } - - if (LnrActrFirgelliNXT.this.killCurrentAction) break; - doWait(LnrActrFirgelliNXT.this.tick_wait/2); - } - - // stop the motor - LnrActrFirgelliNXT.this.encoderMotor.stop(); - stop(); // potentially redundant state-setting when user calls stop() - LnrActrFirgelliNXT.this.tachoCount=temptacho-LnrActrFirgelliNXT.this.encoderMotor.getTachoCount(); - - // set the power back (if changed) - if (LnrActrFirgelliNXT.this.distanceTicks-tacho<=4&&power>80) - LnrActrFirgelliNXT.this.encoderMotor.setPower(LnrActrFirgelliNXT.this.motorPower); - } - } - - private static void doWait(long milliseconds) { - try { - Thread.sleep(milliseconds); - } catch (InterruptedException e) { - ; // do nothing - } - } - - /**Immediately stop any current actuator action. - * @see LinearActuator#move(int,boolean) - */ - public void stop() { - this.killCurrentAction = true; - this.isMoveCommand = false; - - } - - /** Returns the absolute tachometer (encoder) position of the actuator shaft. The zero position of the actuator shaft is where - * resetTachoCount() was last called or the position of the shaft when instantiated. - *

- * The Firgelli L12-NXT-50 & 100 use 0.5 mm/encoder tick. eg: 200 ticks=100 mm. - * - * @return tachometer count in encoder ticks. - * @see #resetTachoCount - */ - public int getTachoCount() { - return this.tachoCount; - } - - /**Resets the tachometer (encoder) count to zero at the current actuator shaft position. - * @see #getTachoCount - */ - public void resetTachoCount() { - this.tachoCount=0; - } - -} - diff --git a/ev3classes/src/main/java/lejos/hardware/device/MMXMotor.java b/ev3classes/src/main/java/lejos/hardware/device/MMXMotor.java deleted file mode 100644 index 3de5d1d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/MMXMotor.java +++ /dev/null @@ -1,103 +0,0 @@ -package lejos.hardware.device; - -import lejos.robotics.EncoderMotor; - -/** - * Abstraction to drive a basic encoder motor with the NXTMMX motor multiplexer. The - * NXTMMX motor multiplexer device allows you to connect two - * additional motors to your robot using a sensor port. Multiple NXTMMXs can be chained together. - *

- * Use the NXTMMX.getBasicMotor() factory method to retrieve an instance of this class. - * - * @see NXTMMX - * @see MMXRegulatedMotor - * @author Kirk P. Thompson - * - */ -public class MMXMotor implements EncoderMotor { - - NXTMMX mmx; - int channel; - - MMXMotor(NXTMMX mmx, int channel) { - this.mmx=mmx; - this.channel=channel; - setPower(100); - } - - public void setPower(int power) { - power=Math.abs(power); - if (power>100) power=100; - mmx.doCommand(NXTMMX.CMD_SETPOWER, power, channel); - } - - /** - * Sets speed ramping is enabled/disabled for this motor. Default at instantiation is ramping enabled. - * @param doRamping true to enable, false to disable - */ - public void setRamping(boolean doRamping) { - int operand=NXTMMX.MOTPARAM_OP_FALSE; - if (doRamping) operand=NXTMMX.MOTPARAM_OP_TRUE; - mmx.doCommand(NXTMMX.CMD_SETRAMPING, operand, channel); - } - - public int getPower() { - return mmx.doCommand(NXTMMX.CMD_GETPOWER, 0, channel); - } - - public void forward() { - mmx.doCommand(NXTMMX.CMD_FORWARD, 0, channel); - } - - public void backward() { - mmx.doCommand(NXTMMX.CMD_BACKWARD, 0, channel); - } - - public void stop() { - mmx.doCommand(NXTMMX.CMD_STOP, 0, channel); - } - - public void flt() { - mmx.doCommand(NXTMMX.CMD_FLT, 0, channel); - } - - /** - * Return true if the motor is moving. Note that this method reports based on the current control - * state (i.e. commanded to move) and not if the motor is actually moving. This means a motor may be stalled but this - * method would return true. - * - * @return true if the motor is executing a movement command, false if stopped. - */ - public boolean isMoving() { - return NXTMMX.MOTPARAM_OP_TRUE==mmx.doCommand(NXTMMX.CMD_ISMOVING, 0, channel); - } - - /* (non-Javadoc) - * @see lejos.robotics.Encoder#getTachoCount() - */ - public int getTachoCount() { - return mmx.doCommand(NXTMMX.CMD_GETTACHO, 0, channel); - } - - /** - * Reset the the tachometer count. TODO verify => Calling this method will stop any current motor action. This is imposed by the HiTechic - * Motor Controller firmware. - */ - public synchronized void resetTachoCount() { - mmx.doCommand(NXTMMX.CMD_RESETTACHO, 0, channel); - } - - /** - * Disable or Enable internal motor controller speed regulation. Setting this to true will cause - * the motor controller firmware to adjust the motor power to compensate for changing loads in order to maintain - * a constant motor speed. Default at instantiation is false. - * - * @param regulate true to enable regulation, true otherwise. - */ - public void setRegulate(boolean regulate){ - int operand=NXTMMX.MOTPARAM_OP_FALSE; - if (regulate) operand=NXTMMX.MOTPARAM_OP_TRUE; - mmx.doCommand(NXTMMX.CMD_SETREGULATE, operand, channel); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/MMXRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/device/MMXRegulatedMotor.java deleted file mode 100644 index 99367c1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/MMXRegulatedMotor.java +++ /dev/null @@ -1,230 +0,0 @@ -package lejos.hardware.device; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; -import lejos.utility.Delay; - -/** -* Abstraction to drive a regulated encoder motor with the NXTMMX motor multiplexer. -* The -* NXTMMX motor multiplexer device allows you to connect two -* additional motors to your robot using a sensor port. Multiple NXTMMXs can be chained together. -*

-* Use the NXTMMX.getRegulatedMotor() factory method to retrieve an instance of this class. -* -* @see NXTMMX -* @author Kirk P. Thompson -* -*/ -public class MMXRegulatedMotor extends MMXMotor implements RegulatedMotor { - static final int LISTENERSTATE_STOP = 0; - static final int LISTENERSTATE_START = 1; - private final int MOTOR_MAX_DPS=Math.round(mmx.getVoltage()*100); - private Object lockObj = new Object(); - - RegulatedMotorListener listener; - - MMXRegulatedMotor(NXTMMX mmx, int channel) { - super(mmx, channel); - } - - - public void addListener(@SuppressWarnings("hiding") RegulatedMotorListener listener) { - this.listener = listener; - } - - void doListenerState(int listenerState) { - synchronized (lockObj) { - if (this.listener == null) return; - if (listenerState == LISTENERSTATE_STOP) { - // wait for a complete stop before notifying -// new Thread(new Runnable(){ -// public void run() { -// waitComplete(); -// listener.rotationStopped(MMXRegulatedMotor.this, getTachoCount(), false, System.currentTimeMillis()); -// }}).start(); - listener.rotationStopped(MMXRegulatedMotor.this, getTachoCount(), false, System.currentTimeMillis()); - } else { - this.listener.rotationStarted(this, getTachoCount(), false, System.currentTimeMillis()); - } - } - } - - public RegulatedMotorListener removeListener() { - RegulatedMotorListener old = this.listener; - this.listener = null; - return old; - } - - /** - * Return the current rotational speed calculated from the encoder position every 100 ms. This will - * likely differ from what was specified in setSpeed. - * - * @return The current rotational speed in deg/sec - */ - public int getRotationSpeed() { - return Math.round(.01f * mmx.doCommand(NXTMMX.CMD_GETSPEED, 0, channel)); - } - - public void stop(boolean immediateReturn) { - super.stop(); - if (!immediateReturn) waitComplete(); - } - - public void flt(boolean immediateReturn) { - super.flt(); - if (!immediateReturn) waitComplete(); - } - - public synchronized void waitComplete() { - while (isMoving()) { - Delay.msDelay(50); - } - } - - /** - * Rotate by the requested number of degrees while blocking until completion. - * - * @param angle number of degrees to rotate relative to the current position. - */ - public void rotate(int angle) { - rotate(angle, false); - } - - /** - * Rotate to the target angle while blocking until completion. - * - * @param limitAngle Angle [in degrees] to rotate to. - */ - public void rotateTo(int limitAngle) { - rotateTo(limitAngle, false); - } - - /** - * Rotate by the requested number of degrees with option for wait until completion or immediate return where the motor - * completes its rotation asynchronously. - * - * @param degrees number of degrees to rotate relative to the current position. - * @param immediateReturn if true, do not wait for the move to complete. false will block - * until the rotation completes. - */ - public void rotate(int degrees, boolean immediateReturn){ - mmx.doCommand(NXTMMX.CMD_ROTATE, degrees, channel); - if (!immediateReturn) mmx.waitRotateComplete(channel); - } - - /** - * Rotate to the target angle with option for wait until completion or immediate return where the motor - * completes its rotation asynchronously. - * - * @param limitAngle Angle [in degrees] to rotate to. - * @param immediateReturn if true, do not wait for the move to complete. false will block - * until the rotation completes. - */ - public void rotateTo(int limitAngle, boolean immediateReturn){ - mmx.doCommand(NXTMMX.CMD_ROTATE_TO, limitAngle, channel); - if (!immediateReturn) mmx.waitRotateComplete(channel); - } - - /** - * Sets desired motor speed, in degrees per second. - *

- * The NXTMMX does not provide speed control per se (just power) so we approximate the power value used - * based on the requested degress/sec (dps) passed in speed. This means if you request 400 dps, - * the actual dps value - * may not reflect that. Setting speed during a rotate method will have no effect on the running rotate - * but will on the next rotate - * method call. - *

- * experimental data gives: dps=8.1551*power+32.253 (unloaded @ 8.83V) - *

- * Note:The NXTMMX doesn't seem to want to drive the standard NXT motor below ~40 dps. - * @param speed Motor speed in degrees per second - * @see #getSpeed - * @see #setPower - */ - public void setSpeed(int speed) { - speed=Math.abs(speed); - if (speed > MOTOR_MAX_DPS) speed=MOTOR_MAX_DPS; - float power=(speed-32.253f)/8.1551f; - if (power<0) power=0; - super.setPower(Math.round(power)); - } - - /** - * Return the current target speed. - * @return Motor speed in degrees per second. - * @see #setSpeed - * @see #getPower - */ - public int getSpeed() { - return Math.round(8.1551f*super.getPower()+32.253f); - } - - public float getMaxSpeed() { - return MOTOR_MAX_DPS; - } - - - public boolean isStalled() { - return NXTMMX.MOTPARAM_OP_TRUE==mmx.doCommand(NXTMMX.CMD_ISSTALLED, 0, channel); - } - - /** - * NOT IMPLEMENTED as the NXTMMX motor controller does not support this command. - */ - public void setStallThreshold(int error, int time) { - // do nothing - } - - /** - * Sets speed ramping is enabled/disabled for this motor. The RegulatedMotor interface - * specifies this in degrees/sec/sec - * but the NXTMMX does not allow the rate to be changed, just if the motor uses smooth - * acceleration or not so we use the acceleration - * parameter to specify ramping state.

Default at instantiation is ramping enabled. - * @param acceleration >0 means NXTMMX internal ramping is enabled otherwise disabled - * @see MMXMotor#setRamping(boolean) - */ - public void setAcceleration(int acceleration){ - super.setRamping(acceleration>0); - } - - /** - * Return the angle that this Motor is rotating to or last rotated to. - * @return angle in degrees. 0 if no rotate method has been intiated. - */ - public int getLimitAngle() { - return mmx.doCommand(NXTMMX.CMD_GETLIMITANGLE, 0, channel); - } - - - @Override - public void close() { - // Do nothing - } - - - @Override - public void synchronizeWith(RegulatedMotor[] syncList) - { - // TODO Auto-generated method stub - - } - - - @Override - public void startSynchronization() - { - // TODO Auto-generated method stub - - } - - - @Override - public void endSynchronization() - { - // TODO Auto-generated method stub - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/MSC.java b/ev3classes/src/main/java/lejos/hardware/device/MSC.java deleted file mode 100644 index c630ae6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/MSC.java +++ /dev/null @@ -1,138 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * This class has been designed to manage the device - * MSC8, Mindsensors NXT Servo which manages up to 8 RC Servos. - * - * For example, do: - * - * msc.servo1.setAngle(angle) - * - * to set the angle of the servo at location 1. - * - * Many thanks to Luis Bunuel (bunuel66@hotmail.com) in Testing process - * - * @author Juan Antonio Brenha Moral - * - */ -public class MSC extends I2CSensor { - public static final byte NXTSERVO_ADDRESS = (byte)0xb0; - public static final byte MSC8_VBATT = 0x41;//The I2C Register to read the battery - - /** - * Servo at location 1 - */ - public MServo servo1; - - /** - * Servo at location 2 - */ - public MServo servo2; - - /** - * Servo at location 3 - */ - public MServo servo3; - - /** - * Servo at location 4 - */ - public MServo servo4; - - /** - * Servo at location 5 - */ - public MServo servo5; - - /** - * Servo at location 6 - */ - public MServo servo6; - - /** - * Servo at location 7 - */ - public MServo servo7; - - /** - * Servo at location 8 - */ - public MServo servo8; - - private MServo[] arrServo; //ServoController manages up to 8 RC Servos - - //I2C - private I2CPort portConnected; - - - private void init(I2CPort port) - { - portConnected = port; - - servo1 = new MServo(portConnected,1); - servo2 = new MServo(portConnected,2); - servo3 = new MServo(portConnected,3); - servo4 = new MServo(portConnected,4); - servo5 = new MServo(portConnected,5); - servo6 = new MServo(portConnected,6); - servo7 = new MServo(portConnected,7); - servo8 = new MServo(portConnected,8); - - arrServo = new MServo[8]; - arrServo[0] = servo1; - arrServo[1] = servo2; - arrServo[2] = servo3; - arrServo[3] = servo4; - arrServo[4] = servo5; - arrServo[5] = servo6; - arrServo[6] = servo7; - arrServo[7] = servo8; - } - - /** - * - * Constructor - * - * @param port the NXTServo is connected to - * - */ - public MSC(Port port){ - super(port); - this.port.setType(TYPE_LOWSPEED_9V); - this.setAddress(NXTSERVO_ADDRESS); - } - - public MSC(I2CPort port){ - super(port); - } - - /** - * Method to get an RC Servo in from the NXTServo - * - * @param location location of the servo (from 1 to 8) - * @return the MServo object - * - */ - public MServo getServo(int location){ - return arrServo[location-1]; - } - - - /** - * Read the battery voltage data from - * NXTServo module (in millivolts) - * - * @return the battery voltage in millivolts - */ - public int getBattery(){ - byte[] bufReadResponse= new byte[1]; - getData(MSC8_VBATT, bufReadResponse, 1); - - // 37 is calculated from 4700 mv /128 - return(37*(0xFF & bufReadResponse[0])); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/MServo.java b/ev3classes/src/main/java/lejos/hardware/device/MServo.java deleted file mode 100644 index d7e5177..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/MServo.java +++ /dev/null @@ -1,147 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.sensor.I2CSensor; - -/** - * MServo, is a abstraction to model any RC Servo (continuous and non continuous) plugged to - * - * @author Juan Antonio Brenha Moral - * - */ -public class MServo extends I2CSensor{ - //private SensorPort portConnected;//Where is plugged in NXT Brick - private int servoPosition = 0; //Position where Servo has been plugged - private final byte SERVO1_POSITION = 0x5A; //The place where RC Servo has been plugged - private final byte SERVO1_SPEED = 0x52; - - //Default Values - private int angle = 0; - private int pulse = 0; - private int minAngle = 0;//Degree - private int maxAngle = 180;//Degrees - private int minPulse = 650;//500;//Ms - private int maxPulse = 2350;//2500;//Ms - - /** - * - * The initial Constructor. - * This constructor establish where is plugged NXTServo on NXT Brick, - * where the RC Servo is plugged into NXTServo - * - * @param port - * @param location - * - */ - public MServo(I2CPort port, int location){ - super(port); - this.servoPosition = location; - } - - /** - * - * The initial Constructor. - * This constructor establish where is plugged NXTServo on NXT Brick, - * where the RC Servo is plugged into NXTServo - * - * @param port - * @param location - * @param servoName - * - */ - public MServo(I2CPort port, int location, String servoName){ - super(port); - this.servoPosition = location; - } - - /** - * - * Constructor with the feature to set min, max and init angle - * - * @param port - * @param location - * @param servoName - * @param min_angle - * @param max_angle - * - */ - public MServo(I2CPort port, int location, String servoName, int min_angle, int max_angle){ - this(port,location,servoName); - - this.minAngle = min_angle; - this.maxAngle = max_angle; - } - - /* - * Used to make a Linear Interpolation - * - * From the HP Calculator idea: - * http://h10025.www1.hp.com/ewfrf/wc/fastFaqLiteDocument?lc=es&cc=mx&docname=bsia5214&dlc=es&product=20037 - * - */ - private float getLinearInterpolation(float x,float x1, float x2, float y1, float y2){ - float y; - y = ((y2-y1)/(x2-x1))*(x-x1) + y1; - - return y; - } - - /** - * This method set the pulse in a RC Servo. - * - * Note:Pulse range is: 500-2500, but internally - * it is necessary to divide into 2 - * - * @param pulse the pulse width - * - */ - public void setPulse(int pulse){ - this.pulse = pulse; - int internalPulse = Math.round(pulse/10); - this.setAddress(MSC.NXTSERVO_ADDRESS); - sendData(SERVO1_POSITION + servoPosition - 1, (byte)internalPulse); - } - - /** - * Return the pulse used in last operation - * - * @return the pulse - * - */ - public int getPulse(){ - return pulse; - } - - /** - * Method to set an Angle in a RC Servo. - * - * @param angle the angle - * - */ - public void setAngle(int angle){ - this.angle = angle; - this.pulse = Math.round(getLinearInterpolation(angle,minAngle,maxAngle,minPulse,maxPulse)); - this.setPulse(pulse); - } - - /** - * Return the angle used in last operation - * - * @return the angle - * - */ - public int getAngle(){ - return angle; - } - - /** - * Method to set the Speed in a RC Servo. - * - * @param speed the speed - * - */ - public void setSpeed(int speed){ - this.setAddress(MSC.NXTSERVO_ADDRESS); - sendData((SERVO1_SPEED + servoPosition - 1), (byte)speed); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/MindSensorsNumPad.java b/ev3classes/src/main/java/lejos/hardware/device/MindSensorsNumPad.java deleted file mode 100644 index 309f231..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/MindSensorsNumPad.java +++ /dev/null @@ -1,269 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; -import lejos.utility.Delay; - -/** - * LeJOS driver for the Mindsensors NumericPad. - * - * @author Rudolf Lapie - */ -public class MindSensorsNumPad extends I2CSensor { - // Driver was originally contributed by Rudolf Lapie - // Interface similar to lejos.nxt.Button added by Sven Köhler - - // instance variables - private static final int NP_ADDRESS = 0xB4; // Default Address - private static final int NP_DATA_REG = 0x00; // Data Register - private static final int POLL_INTERVAL = 10; - - // Indexes of 0123456789*# in #9630825*714 - private static final String IDXMAP = "\04\12\06\03\13\07\02\11\05\01\10\00"; - // private static final String KEYMAP = "0123456789*#"; - - private final byte[] ioBuf = new byte[2]; - private int curButtons; - - // some day, we will throw exception and get ride of this ERROR constant. - public static final int ERROR = -1; - public static final int ID_KEY0 = (1 << 0); - public static final int ID_KEY1 = (1 << 1); - public static final int ID_KEY2 = (1 << 2); - public static final int ID_KEY3 = (1 << 3); - public static final int ID_KEY4 = (1 << 4); - public static final int ID_KEY5 = (1 << 5); - public static final int ID_KEY6 = (1 << 6); - public static final int ID_KEY7 = (1 << 7); - public static final int ID_KEY8 = (1 << 8); - public static final int ID_KEY9 = (1 << 9); - public static final int ID_STAR = (1 << 10); - public static final int ID_HASH = (1 << 11); - - - protected void init() - { - - // This is the initialization used by the Xander's RobotC driver - // and the code submitted by Rudolf Lapie. - sendGroup(0x2B, "\001\001\000\000\001\001\377\002"); - sendGroup(0x41, "\017\012\017\012\017\012\017\012\017\012\017\012\017\012"); - sendGroup(0x4F, "\017\012\017\012\017\012\017\012\017\012\017\012"); - sendGroup(0x5C, "\013\040\014"); - sendGroup(0x7B, "\013"); - sendGroup(0x7D, "\234\145\214"); - - // This are the initialization as in the NXC driver by MindSensors. - // For some reason, it differs from the one the RobotC driver and - // the driver submitted by Rudolf Lapie. - // sendGroup(0x2B, "\001\001\000\000\001\001\377\002"); - // sendGroup(0x41, "\017\012\017\012\017\012\017\012\017"); - // sendGroup(0x4A, "\012\017\012\017\012\017\012\017"); - // sendGroup(0x52, "\012\017\012\017\012\017\012\017"); - // sendGroup(0x5C, "\013\040\014"); - // sendGroup(0x7D, "\234\145\214"); - - int k = this.readButtonsRaw(); - if (k == ERROR) - k = 0; - this.curButtons = k; - - } - - /** - * Constructor for objects of the NumericPad of Mindsensors. It assumes that - * you didn't change the I²C address of the device. - * - * @param port - * the port number (SensorPort.S1 ... SensorPort.S4) to which the - * numeric pad is connected. - */ - public MindSensorsNumPad(I2CPort port) { - super(port, NP_ADDRESS); - init(); - } - - /** - * Constructor for objects of the NumericPad of Mindsensors. It assumes that - * you didn't change the I²C address of the device. - * - * @param port - * the port number (SensorPort.S1 ... SensorPort.S4) to which the - * numeric pad is connected. - */ - public MindSensorsNumPad(Port port) { - super(port, NP_ADDRESS); - init(); - } - - private void sendGroup(int reg, String data) { - int len = data.length(); - byte[] b = new byte[len]; - for (int i=0; i POLL_INTERVAL) - toWait = POLL_INTERVAL; - Delay.msDelay(toWait); - - oldDown = newDown; - } - } - - /** - * Waits for some button to be pressed. If a button is already pressed, it - * must be released and pressed again. - * - * @return the ID of the button that has been pressed or in rare cases a bitmask of button IDs - */ - public int waitForAnyPress() { - return this.waitForAnyPress(0); - } - - /** - * Waits for some button to be pressed. If a button is already pressed, it - * must be released and pressed again. - * - * @param timeout The maximum number of milliseconds to wait - * @return the ID of the button that has been pressed or in rare cases a bitmask of button IDs, - * 0 if the given timeout is reached - */ - public int waitForAnyPress(int timeout) { - long end = (timeout == 0 ? 0x7fffffffffffffffL : System.currentTimeMillis() + timeout); - - int oldDown = curButtons; - while (true) - { - int newDown = readButtonsRaw(); - if (newDown == ERROR) - newDown = oldDown; - - curButtons = newDown; - int pressed = newDown & (~oldDown); - if (pressed != 0) - return rawToOrdered(pressed); - - long toWait = end - System.currentTimeMillis(); - if (toWait <= 0) - return 0; - if (toWait > POLL_INTERVAL) - toWait = POLL_INTERVAL; - Delay.msDelay(toWait); - - oldDown = newDown; - } - } - - private int rawToOrdered(int x) - { - int r = 0; - int len = IDXMAP.length(); - for (int i=0; i> j) & 1) << i; - } - return r; - } - -// private String rawToString(int x) -// { -// StringBuilder sb = new StringBuilder(12); -// int len = IDXMAP.length(); -// for (int i=0; i - * Create an instance of this class and use the factory methods to provide a MMXRegulatedMotor or - * MMXMotor instance. - * @see MMXRegulatedMotor - * @see MMXMotor - * @author Kirk P Thompsonn - * - */ -public class NXTMMX extends I2CSensor { - /** - * Represents Motor 1 as indicated on the controller - */ - public static final int MOTOR_M1 = 0; - /** - * Represents Motor 2 as indicated on the controller - */ - public static final int MOTOR_M2 = 1; - - /** - * The default I2C address (0x06) for the NXTMMX. - */ - public static final int DEFAULT_MMX_ADDRESS = 0x6; - - private static final int CHANNELS = 2; - - static final int CMD_FORWARD = 0; - static final int CMD_BACKWARD = 1; - static final int CMD_FLT = 2; - static final int CMD_STOP = 3; - static final int CMD_SETPOWER = 4; - static final int CMD_ROTATE = 5; - static final int CMD_ROTATE_TO = 6; - static final int CMD_GETPOWER = 7; - static final int CMD_RESETTACHO = 8; - static final int CMD_SETRAMPING = 9; - static final int CMD_ISSTALLED = 10; - static final int CMD_ISMOVING = 11; - static final int CMD_SETREGULATE = 12; - static final int CMD_GETTACHO = 13; - static final int CMD_GETSPEED = 14; - static final int CMD_GETLIMITANGLE = 15; - - // motor state management - int[] motorState = {STATE_STOPPED, STATE_STOPPED}; - private static final int STATE_STOPPED = 0; - private static final int STATE_RUNNING_FWD = 1; - private static final int STATE_RUNNING_BKWD = 2; - private static final int STATE_ROTATE_TO = 3; - - // register map for the motor-specific registers - private static final int REG_IDX_ENCODER_TARGET = 0; - private static final int REG_IDX_COMMAND = 1; - private static final int REG_IDX_POWER = 2; -// private static final int REG_IDX_TIME = 3; - private static final int REG_IDX_STATUS = 4; - private static final int REG_IDX_ENCODER_CURRENT = 5; - static final int[][] REGISTER_MAP = // [REG_IDX_xxx][channel/motor ID] - {{0x42, 0x4A}, // Encoder Target (write) : s/int - {0x49, 0x51}, // Command A : byte - {0x46, 0x4E}, // Power (aka speed) : s/byte - {0x47, 0x4F}, // Time : byte - {0x72, 0x73}, // Status : byte - {0x62, 0x66} // Encoder Value (read) : s/int - }; - - // common registers - static final int REG_ENCODERSREAD = REGISTER_MAP[REG_IDX_ENCODER_CURRENT][MOTOR_M1]; // used by tachmonitor to read both encoders at once - private static final int REG_MMXCOMMAND = 0x41; - - // MMX common commands - private static final byte MMXCOMMAND_RESET = 0x52; - private static final byte MMXCOMMAND_BRAKE = 0x43; - private static final byte MMXCOMMAND_FLOAT = 0x63; - - // MMX channel commands - private static final byte MMXCOMMAND_IDX_BRAKE = 0; - private static final byte MMXCOMMAND_IDX_FLOAT = 1; - private static final byte MMXCOMMAND_IDX_ENCODER_RST = 2; - static final byte[][] MMXCOMMAND_MAP = // [MMXCOMMAND_xxx][channel/motor ID] - {{0x41, 0x42}, // Brake - {0x61, 0x62}, // Float - {0x72, 0x73} // tacho reset - }; - - // Command register OR masks - private static final int CMDBIT_SPEED_MODE = 0x01; - private static final int CMDBIT_RAMP = 0x02; - private static final int CMDBIT_ROTATE_RELATIVE = 0x04; - private static final int CMDBIT_ROTATE_MODE = 0x08; - private static final int CMDBIT_BRAKING_MODE = 0x10; - private static final int CMDBIT_HOLD_POSITION = 0x20; -// private static final int CMDBIT_TIMED_MODE = 0x40; - private static final int CMDBIT_GO = 0x80; - - // motor parameters - private int[][] motorParams = new int[5][CHANNELS]; - private static final int MOTPARAM_POWER = 0; // current power value - private static final int MOTPARAM_RAMPING = 1; // 0=false=none, 1=ramped - private static final int MOTPARAM_ENCODER_BRAKING = 2; // 1=brake, 0= float - private static final int MOTPARAM_ENCODER_HOLD = 3; // 1=lock to position after rotation completion, 0=don't - private static final int MOTPARAM_REGULATE = 4; // 1=set CMDBIT_SPEED_MODE on command issue, 0=don't - static final int MOTPARAM_OP_TRUE=1; - static final int MOTPARAM_OP_FALSE=0; - - // motor and monitor instance buckets - Object[] motors= new Object[CHANNELS]; - BUSYMonitor[] bUSYMonitors = new BUSYMonitor[CHANNELS]; - TachoMonitor tachoMonitor; - boolean[] busyMonitorWaiting = {false,false}; - - private static final byte MOTTYPE_EMPTY = -1; - private static final byte MOTTYPE_BASIC = 0; - private static final byte MOTTYPE_REGULATED = 1; - byte[] motorType = {MOTTYPE_EMPTY,MOTTYPE_EMPTY}; - - // I2C buffer - private byte[] buf = new byte[12]; - - private int limitangle[] = {0,0}; - - // When a rotate is issued, an instance monitors the status bits and sets STATE_STOPPED when the command completes. - // Also does any required RegulatedMotorListener STOP and notifies any wait() in waitRotateComplete(). - // Used by rotate() method only. - private class BUSYMonitor extends Thread { - int channel; - BUSYMonitor(int channel){ - this.channel = channel; - } - @Override - public void run(){ - byte buf1[] = {1}; - while ((buf1[0] & 0x0F) != 0) { - Delay.msDelay(50); - //System.out.println("bsy " + buf1[0] + " "); - getData(REGISTER_MAP[REG_IDX_STATUS][channel], buf1, 1); - } - if (motorState[channel]!=STATE_STOPPED) { - motorState[channel]=STATE_STOPPED; - if (motorType[channel]==MOTTYPE_REGULATED) { - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_STOP); - } - } - //System.out.println("busy done"); - // exit any wait for state of [ImmediateReturn = false] - synchronized (bUSYMonitors[channel]) { - busyMonitorWaiting[channel]=false; - bUSYMonitors[channel].notifyAll(); -// System.out.println("*notifyall"); - } - } - } - - // used by MMXRegulatedMotor to monitor/manage tacho-related - private class TachoMonitor extends Thread{ - private static final int POLL_DELAY_MS = 75; - - private boolean threadDie = false; - private int[] TachoCount = new int[CHANNELS]; - private byte[] buffer = new byte[8]; - private volatile float[] degpersec = new float[CHANNELS]; - private float[][] samples = new float[CHANNELS][3]; - private int sampleIndex=0; - private boolean[] ismoving = new boolean[CHANNELS]; - - TachoMonitor(){ - this.setDaemon(true); - } - - synchronized int getTachoCount(int channel) { - return TachoCount[channel]; - } - - synchronized int getSpeed(int channel) { - return (int)(degpersec[channel] * 100); - } - - boolean isMoving(int channel){ - return ismoving[channel]; - } - - @Override - public void run(){ - int retVal; - int failCount; - int[] tachoBegin = new int[CHANNELS]; - long endTime, beginTime, timeDelta; - float[] degpersecAccum = new float[CHANNELS]; - - beginTime = System.currentTimeMillis(); - Main: while (!threadDie){ - Delay.msDelay(POLL_DELAY_MS); - retVal = 0; - try { - getData(REG_ENCODERSREAD, buffer, 8); - } catch (I2CException e) { - retVal = -1; - } - - failCount = 0; - while (retVal < 0) { - if (++failCount>4) { -// System.out.println("fail"); - continue Main; - } - retVal = 0; - try { - getData(REG_ENCODERSREAD, buffer, 8); - } catch (I2CException e) { - retVal = -1; - } - } - - // baseline the time after successful I2C transaction - endTime = System.currentTimeMillis(); - timeDelta = endTime - beginTime; - beginTime = endTime; - - // parse the buffer into the counts - synchronized (this){ - TachoCount[MOTOR_M1] = EndianTools.decodeIntLE(buffer, 0); - TachoCount[MOTOR_M2] = EndianTools.decodeIntLE(buffer, 4); - } - - // Do velocity calcs (deg per sec) - for (int i=0;i= samples[i].length) sampleIndex = 0; - } - // save a dps sample - samples[i][sampleIndex] = (float)Math.abs(TachoCount[i] - tachoBegin[i]) / timeDelta * 250; - tachoBegin[i] = TachoCount[i]; - } - - // average the samples and the last result (degpersec) - for (int ii=0;iiMMXRegulatedMotor instance that is associated with the motorID. - * - * @param motorID The motor ID number. This is indicated on the NXTMMX Motor Controller and is - * represented using {@link #MOTOR_M1} or {@link #MOTOR_M2}. - * @return The MMXRegulatedMotor instance - * @throws IllegalArgumentException if invalid motorID - * @throws UnsupportedOperationException if motorID has already been used for a - * MMXMotor motor instance. - * @see MMXRegulatedMotor - * @see #getBasicMotor - */ - public MMXRegulatedMotor getRegulatedMotor(int motorID) { - getMotor(motorID, MOTTYPE_REGULATED); - return (MMXRegulatedMotor) motors[motorID]; - } - - /** - * Get a MMXMotor instance that is associated with the motorID. - * - * @param motorID The motor ID number. This is indicated on the NXTMMX Motor Controller and is - * represented using {@link #MOTOR_M1} or {@link #MOTOR_M2}. - * @return The MMXMotor instance - * @throws IllegalArgumentException if invalid motorID - * @throws UnsupportedOperationException if motorID has already been used for a - * MMXRegulatedMotor motor instance. - * @see MMXMotor - * @see #getRegulatedMotor - */ - public MMXMotor getBasicMotor(int motorID) { - getMotor(motorID, MOTTYPE_BASIC); - return (MMXMotor) motors[motorID]; - } - - private void getMotor(int motorID, byte motorTypeValue){ - if (motorIDMOTOR_M2) { - throw new IllegalArgumentException("Invalid motor ID"); - } - - if (motorType[motorID]==MOTTYPE_EMPTY) { - switch(motorTypeValue) { - case MOTTYPE_REGULATED: - motors[motorID]=new MMXRegulatedMotor(this, motorID); - //start the tacho monitor if not already for encoder-enabled motor - if (tachoMonitor==null) { - this.tachoMonitor = new TachoMonitor(); - this.tachoMonitor.start(); - } - break; - case MOTTYPE_BASIC: - motors[motorID]=new MMXMotor(this, motorID); - } - motorType[motorID]=motorTypeValue; - } - if (motorType[motorID]!=motorTypeValue) { - throw new UnsupportedOperationException("Wrong motor type"); - } - } - - boolean tachoMonitorAlive() { - return tachoMonitor!=null && tachoMonitor.isAlive(); - } - - /** - * Execute a command. designed to never block because it is shared across two motors. The rotate WAITS are done - * in the MMXRegulatedMotor class - * @param command the command - * @param operand the value from the caller. Mostly not used and set to 0 - * @param channel the channel: MOTOR_M1, MOTOR_M2 - * @return a value depending on the command - */ - synchronized int doCommand(int command, int operand, int channel) { - byte workingByte=0; - int commandRetVal=0; - - switch (command) { - case CMD_FORWARD: - case CMD_BACKWARD: - if (command==CMD_FORWARD && motorState[channel]==STATE_RUNNING_FWD) break; - if (command==CMD_BACKWARD && motorState[channel]==STATE_RUNNING_BKWD) break; - if (motorType[channel]==MOTTYPE_REGULATED) { - if (motorState[channel]!=STATE_STOPPED) { - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_STOP); - } - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_START); - } - // command + 1 = STATE_RUNNING_BKWD or STATE_RUNNING_FWD - setDirection(channel, command + 1); - commandMotor(channel, 0); - break; - case CMD_FLT: - workingByte = MMXCOMMAND_MAP[MMXCOMMAND_IDX_FLOAT][channel]; - case CMD_STOP: - if (command==CMD_STOP) workingByte = MMXCOMMAND_MAP[MMXCOMMAND_IDX_BRAKE][channel]; - sendData(REG_MMXCOMMAND, workingByte); - if (motorType[channel]==MOTTYPE_REGULATED && motorState[channel]!=STATE_STOPPED ) { - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_STOP); - } - - motorState[channel]=STATE_STOPPED; - break; - case CMD_SETPOWER: // requires positive value and validation done in caller - // exit if no change - if (motorParams[MOTPARAM_POWER][channel]==operand) break; - - // set the (abs) power value in global param array - motorParams[MOTPARAM_POWER][channel] = operand; - - // set the power with proper sign based on direction - workingByte = (byte)operand; - if (motorState[channel]==STATE_RUNNING_BKWD ) { - workingByte *= -1; - } - sendData(REGISTER_MAP[REG_IDX_POWER][channel], workingByte); - - // if not running or in a rotate, exit - if (motorState[channel]==STATE_STOPPED || motorState[channel]==STATE_ROTATE_TO) break; - - // set the power if running (but not in a rotate) to take effect immediately - commandMotor(channel, 0); - break; - case CMD_ROTATE: - case CMD_ROTATE_TO: - if (motorType[channel]==MOTTYPE_REGULATED) { - if (motorState[channel]!=STATE_STOPPED) { - // ensure the motor has stopped before new rotate so listener event timing is correct -// sendData(REG_MMXCOMMAND, MMXCOMMAND_MAP[MMXCOMMAND_IDX_BRAKE][channel]); -// while (tachoMonitor.isMoving(channel)) Delay.msDelay(50); - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_STOP); - } - ((MMXRegulatedMotor) motors[channel]).doListenerState(MMXRegulatedMotor.LISTENERSTATE_START); - } - rotate(channel, operand, command); - break; - case CMD_GETPOWER: - commandRetVal=motorParams[MOTPARAM_POWER][channel]; - break; - case CMD_GETTACHO: - commandRetVal=getEncoderValue(channel); - break; - case CMD_RESETTACHO: - // reset encoder/tacho - sendData(REG_MMXCOMMAND, MMXCOMMAND_MAP[MMXCOMMAND_IDX_ENCODER_RST][channel]); - Delay.msDelay(50); - break; - case CMD_ISMOVING: - commandRetVal=MOTPARAM_OP_TRUE; - if (motorState[channel]==STATE_STOPPED) commandRetVal=MOTPARAM_OP_FALSE; - // over-ride previous decision if regulated motor and it is moving - if (tachoMonitorAlive()) { - commandRetVal = tachoMonitor.isMoving(channel)?MOTPARAM_OP_TRUE:MOTPARAM_OP_FALSE; - } - break; - case CMD_ISSTALLED: - commandRetVal=MOTPARAM_OP_FALSE; - if (tachoMonitorAlive() && motorState[channel]!=STATE_STOPPED && !tachoMonitor.isMoving(channel)) { - commandRetVal=MOTPARAM_OP_TRUE; - } - break; - case CMD_SETREGULATE: - motorParams[MOTPARAM_REGULATE][channel]=operand; //1=true, 0=false - break; - case CMD_GETSPEED: - commandRetVal = 0; - if (tachoMonitorAlive()) { - commandRetVal = tachoMonitor.getSpeed(channel); - } - break; - case CMD_GETLIMITANGLE: - commandRetVal = limitangle[channel]; - break; - case CMD_SETRAMPING: - motorParams[MOTPARAM_RAMPING][channel]=operand; //1=true, 0=false - break; - - default: - throw new IllegalArgumentException("Invalid Command"); - } - return commandRetVal; - } - - private void setDirection(int channel, int directionState) { - if (motorState[channel]!=directionState){ - // set the power with proper sign based on desired direction state - motorState[channel]=directionState; - byte workingByte=(byte) motorParams[MOTPARAM_POWER][channel]; - if (motorState[channel]==STATE_RUNNING_BKWD ) { - workingByte *= -1; - } - sendData(REGISTER_MAP[REG_IDX_POWER][channel], workingByte); - } - } - - private int getEncoderValue(int channel) { - // TODO the old mmx getTacho requeried i2c on error return. Do we need this? - - // use latest tachoMonitor value for the motor if available - if (tachoMonitorAlive()) { - return tachoMonitor.getTachoCount(channel); - } - // .. otherwise, query the controller to get it - getData(REGISTER_MAP[REG_IDX_ENCODER_CURRENT][channel], buf, 4); - return EndianTools.decodeIntLE(buf, 0); - } - - private void rotate(int channel, int value, int cmd) { - byte workingByte = CMDBIT_ROTATE_MODE; - - // set cmd bits - if (cmd == CMD_ROTATE) { - workingByte |= CMDBIT_ROTATE_RELATIVE; //2 - } - // TODO these two need to be settable somewhere - if (motorParams[MOTPARAM_ENCODER_BRAKING][channel] == MOTPARAM_OP_TRUE) { - workingByte |= CMDBIT_BRAKING_MODE; //4 - } - if (motorParams[MOTPARAM_ENCODER_HOLD][channel] == MOTPARAM_OP_TRUE) { - workingByte |= CMDBIT_HOLD_POSITION; //5 - } - - // Wait until previous busyMonitor is done TODO -// if (bUSYMonitors[channel]!=null){ -// try { -// System.out.println("prejoin"); -// if (bUSYMonitors[channel].isAlive()) bUSYMonitors[channel].join(); -// System.out.println("postjoin"); -// } catch (InterruptedException e) { -// // ignore -// } -// } -// while(busyMonitorWaiting[channel]) Delay.msDelay(50); - - // set the target angle - this.limitangle[channel] = value; // for getLimitAngle() - EndianTools.encodeIntLE(value, buf, 0); - sendData(REGISTER_MAP[REG_IDX_ENCODER_TARGET][channel], buf, 4); - motorState[channel] = STATE_ROTATE_TO; - - // set up the RegulatedMotorListener notifier and waitToComplete - // notifier for the rotate - bUSYMonitors[channel] = new BUSYMonitor(channel); - // do the rotate - commandMotor(channel, workingByte); - bUSYMonitors[channel].start(); - } - - void waitRotateComplete(int channel) { - synchronized (bUSYMonitors[channel]) { - busyMonitorWaiting[channel] = true; - while (busyMonitorWaiting[channel]) { - try { - bUSYMonitors[channel].wait(); - } catch (InterruptedException e) { - // ignore - } - } - } - } - - /** - * sets motor command mask to the NXTMMX motor command register with appropriate bit masks set - * on passed command value. - * @param channel motor ID - * @param maskValue value to be ORed (CMDBITs) - */ - private void commandMotor(int channel, int maskValue){ - byte workingByte = (byte)((CMDBIT_GO | maskValue) & 0xff); - - if (motorParams[MOTPARAM_REGULATE][channel] == MOTPARAM_OP_TRUE) workingByte |= CMDBIT_SPEED_MODE; - if (motorParams[MOTPARAM_RAMPING][channel] == MOTPARAM_OP_TRUE) workingByte |= CMDBIT_RAMP; - // send the message. - sendData(REGISTER_MAP[REG_IDX_COMMAND][channel], workingByte); - } - - /** - * Returns the voltage supplied to the NXTMMX - * @return the voltage in volts - */ - public synchronized float getVoltage(){ - getData(REG_MMXCOMMAND, buf, 1); - // 37 is the constant given by Mindsensors support 5/2011 to return millivolts. KPT - return (37f*(buf[0]&0xff))*.001f; - } - - private void synchStop(byte command){ - sendData(REG_MMXCOMMAND, command); - for (int channel=0;channel arrLSC; - private final int MAXIMUM_LSC = 4; - - //Exception handling - private final String ERROR_SERVO_DEFINITION = "Error with Servo Controller definition"; - private final String ERROR_SPI_CONFIGURATION = "Error in SPI Configuration"; - - //I2C - private I2CPort portConnected; - private final byte SPI_PORT[] = {0x01,0x02,0x04,0x08};//SPI Ports where you connect LSC - public static final byte NXTE_ADDRESS = 0x50; - private final byte REGISTER_IIC = (byte)0xF0;//NXTe IIC address - - private void init(I2CPort port) - { - portConnected = port; - - arrLSC = new ArrayList(); - - - this.sendData((int)this.REGISTER_IIC, (byte)0x0c); - - } - /** - * Constructor - * - * @param port - */ - public NXTe(I2CPort port){ - super(port, NXTE_ADDRESS); - init(this.port); - } - - public NXTe(Port port){ - super(port, NXTE_ADDRESS, TYPE_LOWSPEED_9V); - init(this.port); - } - - /** - * Add a LSC, Lattebox Servo Controller - * - * @param SPI_PORT - * @throws Exception - */ - public void addLSC(int SPI_PORT) throws ArrayIndexOutOfBoundsException{ - if(arrLSC.size() <= MAXIMUM_LSC){ - LSC LSCObj = new LSC(this.portConnected,this.SPI_PORT[SPI_PORT]); - arrLSC.add(LSCObj); - }else{ - //throw new ArrayIndexOutOfBoundsException(ERROR_SERVO_DEFINITION); - throw new ArrayIndexOutOfBoundsException(); - } - } - - /** - * Get a LSC, Lattebox Servo Controller - * - * @param index in the array - * @return the LSC object - */ - public LSC getLSC(int index){ - return arrLSC.get(index); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/device/PFLink.java b/ev3classes/src/main/java/lejos/hardware/device/PFLink.java deleted file mode 100644 index 7586153..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/PFLink.java +++ /dev/null @@ -1,246 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; -import lejos.utility.Delay; - -/** - * Class for controlling PF Motors with MindSensors NRLink-Nx - * - * @author Alexander Vegh - * - */ -public class PFLink extends I2CSensor { - - public final static byte NR_RANGE_SHORT = 0x53; - public final static byte NR_RANGE_LONG = 0x4c; - - private static final byte NR_ID = 0X02; - private static final byte NR_COMMAND = 0X41; - private final static byte NR_RUN = 0X52; - private final static byte NR_SPEED_SLOW = 0X44; - private final static byte NR_FLUSH = 0X46; - private static final byte NR_SELECT_PF = 0X50; - - - public static final int MOTOR_CH1_A_FLOAT = 0x50; - public static final int MOTOR_CH1_A_FORWARD = 0x53; - public static final int MOTOR_CH1_A_REVERSE = 0x56; - public static final int MOTOR_CH1_A_BRAKE = 0x59; - - public static final int MOTOR_CH1_B_FLOAT = 0x5C; - public static final int MOTOR_CH1_B_FORWARD = 0x5F; - public static final int MOTOR_CH1_B_REVERSE = 0x62; - public static final int MOTOR_CH1_B_BRAKE = 0x65; - - public static final int MOTOR_CH2_A_FLOAT = 0x68; - public static final int MOTOR_CH2_A_FORWARD = 0x6B; - public static final int MOTOR_CH2_A_REVERSE = 0x6E; - public static final int MOTOR_CH2_A_BRAKE = 0x71; - - public static final int MOTOR_CH2_B_FLOAT = 0x74; - public static final int MOTOR_CH2_B_FORWARD = 0x77; - public static final int MOTOR_CH2_B_REVERSE = 0x7A; - public static final int MOTOR_CH2_B_BRAKE = 0x7D; - - public static final int MOTOR_CH3_A_FLOAT = 0x80; - public static final int MOTOR_CH3_A_FORWARD = 0x83; - public static final int MOTOR_CH3_A_REVERSE = 0x86; - public static final int MOTOR_CH3_A_BRAKE = 0x89; - - public static final int MOTOR_CH3_B_FLOAT = 0x8C; - public static final int MOTOR_CH3_B_FORWARD = 0x8F; - public static final int MOTOR_CH3_B_REVERSE = 0x92; - public static final int MOTOR_CH3_B_BRAKE = 0x95; - - public static final int MOTOR_CH4_A_FLOAT = 0x98; - public static final int MOTOR_CH4_A_FORWARD = 0x9B; - public static final int MOTOR_CH4_A_REVERSE = 0x9E; - public static final int MOTOR_CH4_A_BRAKE = 0xA1; - - public static final int MOTOR_CH4_B_FLOAT = 0xA4; - public static final int MOTOR_CH4_B_FORWARD = 0xA7; - public static final int MOTOR_CH4_B_REVERSE = 0xAA; - public static final int MOTOR_CH4_B_BRAKE = 0xAD; - - public static final int COMBO_CH1_A_FORWARD_B_FORWARD = 0XB0; - public static final int COMBO_CH1_A_FORWARD_B_REVERSE = 0XB3; - public static final int COMBO_CH1_A_REVERSE_B_FORWARD = 0XB6; - public static final int COMBO_CH1_A_REVERSE_B_REVERSE = 0XB9; - - public static final int COMBO_CH2_A_FORWARD_B_FORWARD = 0XBC; - public static final int COMBO_CH2_A_FORWARD_B_REVERSE = 0XBF; - public static final int COMBO_CH2_A_REVERSE_B_FORWARD = 0XC2; - public static final int COMBO_CH2_A_REVERSE_B_REVERSE = 0XC5; - - public static final int COMBO_CH3_A_FORWARD_B_FORWARD = 0XC8; - public static final int COMBO_CH3_A_FORWARD_B_REVERSE = 0XCB; - public static final int COMBO_CH3_A_REVERSE_B_FORWARD = 0XCE; - public static final int COMBO_CH3_A_REVERSE_B_REVERSE = 0XD1; - - public static final int COMBO_CH4_A_FORWARD_B_FORWARD = 0XD4; - public static final int COMBO_CH4_A_FORWARD_B_REVERSE = 0XD7; - public static final int COMBO_CH4_A_REVERSE_B_FORWARD = 0XDA; - public static final int COMBO_CH4_A_REVERSE_B_REVERSE = 0XDD; - - - private static final int[] COMMANDS = new int[]{ - - 0x50, 0x01, 0x00, //Motor Ch1 A Float - 0x53, 0x01, 0x10, //Motor Ch1 A Forward - 0x56, 0x01, 0x20, //Motor Ch1 A Reversed - 0x59, 0x01, 0x30, //Motor Ch1 A Break - - 0x5C, 0x01, 0x00, //Motor Ch1 B Float - 0x5F, 0x01, 0x40, //Motor Ch1 B Forward - 0x62, 0x01, 0x80, //Motor Ch1 B Reversed - 0x65, 0x01, 0xc0, //Motor Ch1 B Break - - 0x68, 0x11, 0x00, //Motor Ch2 A Float - 0x6B, 0x11, 0x10, //Motor Ch2 A Forward - 0x6E, 0x11, 0x20, //Motor Ch2 A Reversed - 0x71, 0x11, 0x30, //Motor Ch2 A Break - - 0x74, 0x11, 0x00, //Motor Ch2 B Float - 0x77, 0x11, 0x40, //Motor Ch2 B Forward - 0x7A, 0x11, 0x80, //Motor Ch2 B Reversed - 0x7D, 0x11, 0xc0, //Motor Ch2 B Break - - 0x80, 0x21, 0x00, //Motor Ch3 A Float - 0x83, 0x21, 0x10, //Motor Ch3 A Forward - 0x86, 0x21, 0x20, //Motor Ch3 A Reversed - 0x89, 0x21, 0x30, //Motor Ch3 A Break - - 0x8C, 0x21, 0x00, //Motor Ch3 B Float - 0x8F, 0x21, 0x40, //Motor Ch3 B Forward - 0x92, 0x21, 0x80, //Motor Ch3 B Reversed - 0x95, 0x21, 0xc0, //Motor Ch3 B Break - - 0x98, 0x31, 0x00, //Motor Ch4 A Float - 0x9B, 0x31, 0x10, //Motor Ch4 A Forward - 0x9E, 0x31, 0x20, //Motor Ch4 A Reversed - 0xA1, 0x31, 0x30, //Motor Ch4 A Break - - 0xA4, 0x31, 0x00, //Motor Ch4 B Float - 0xA7, 0x31, 0x40, //Motor Ch4 B Forward - 0xAA, 0x31, 0x80, //Motor Ch4 B Reversed - 0xAD, 0x31, 0xC0 //Motor Ch4 B Break - }; - - private static final int[] COMBOS = new int[]{ - 0xB0, 0x01, 0x50, // Motor Ch1 A Forw B Forw - 0xB3, 0x01, 0x90, // Motor Ch1 A Forw B Rev - 0xB6, 0x01, 0x60, // Motor Ch1 A Rev B Forw - 0xB9, 0x01, 0xa0, // Motor Ch1 A Rev B Rev - 0xBC, 0x11, 0x50, // Motor Ch2 A Forw B Forw - 0xBF, 0x11, 0x90, // Motor Ch2 A Forw B Rev - 0xC2, 0x11, 0x60, // Motor Ch2 A Rev B Forw - 0xC5, 0x11, 0xa0, // Motor Ch2 A Rev B Rev - 0xC8, 0x21, 0x50, // Motor Ch3 A Forw B Forw - 0xCB, 0x21, 0x90, // Motor Ch3 A Forw B Rev - 0xCE, 0x21, 0x60, // Motor Ch3 A Rev B Forw - 0xD1, 0x21, 0xa0, // Motor Ch3 A Rev B Rev - 0xD4, 0x31, 0x50, // Motor Ch4 A Forw B Forw - 0xD7, 0x31, 0x90, // Motor Ch4 A Forw B Rev - 0xDA, 0x31, 0x60, // Motor Ch4 A Rev B Forw - 0xDD, 0x31, 0xa0 // Motor Ch4 A Rev B Rev - }; - - public PFLink(I2CPort _Port, int address) { - super(_Port, address); - } - - public PFLink(I2CPort _Port) { - super(_Port); - } - - public PFLink(Port _Port, int address) { - super(_Port, address, TYPE_LOWSPEED); - } - - public PFLink(Port _Port) { - super(_Port); - } - - /** - * Should be called once to set up the NRLink for usage in the program - * - * @param _Range Either NR_RANGE_SHORT or NR_RANGE_LONG, which uses more power - */ - public void initialize(byte _Range) { - runCommand(NR_FLUSH); - runCommand(NR_SPEED_SLOW); - runCommand(NR_SELECT_PF); - runCommand(_Range); - } - - /** - * Executes a command - * - * @param command - */ - public void runCommand(int command) { - byte[] buf = new byte[2]; - - buf[0] = NR_ID; - buf[1] = (byte) (command); - sendData(NR_COMMAND, buf, 2); - } - - /** - * Installs a macro into the NRLink - * - * You really should call this only once for a new NRLink since - * it stores them in EEPROM even if turned of. And I have no idea how - * often you can overwrite them before they burn out... - * - * - * @param _Address The address up from 0x40 for the macro - * @param _Macro The macro - */ - public void installMacro(int _Address, byte[] _Macro) { - sendData((byte) _Address, (byte) _Macro.length); - Delay.msDelay(10); - sendData((byte) _Address + 1, _Macro, _Macro.length); - - } - - - /** - * Installs the macro definitions used by this class. - * - * You really should call this only once for a new NRLink since - * it stores them in EEPROM even if turned of. And I have no idea how - * often you can overwrite them before they burn out... - */ - public void installDefaultMacros() { - byte[] buffer = new byte[2]; - - for (int i = 0; i < COMMANDS.length; i += 3) { - buffer[0] = (byte) (COMMANDS[i + 1] & 0xff); - buffer[1] = (byte) (COMMANDS[i + 2] & 0xff); - installMacro(COMMANDS[i], buffer); - } - - for (int i = 0; i < COMBOS.length; i += 3) { - buffer[0] = (byte) (COMBOS[i + 1] & 0xff); - buffer[1] = (byte) (COMBOS[i + 2] & 0xff); - installMacro(COMBOS[i], buffer); - } - } - - /** - * Runs a macro which has been previously installed on the NRLink. - * - * - * @param _Address The address of the macro, one of the MOTOR_* for a single motor - * or one of the COMBO_* macros which work on both motors simultaneously - */ - public void runMacro(int _Address) { - byte[] buf = new byte[2]; - buf[0] = NR_RUN; - buf[1] = (byte) _Address; - sendData(NR_COMMAND, buf, 2); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/PFMate.java b/ev3classes/src/main/java/lejos/hardware/device/PFMate.java deleted file mode 100644 index 202cd65..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/PFMate.java +++ /dev/null @@ -1,125 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * Supports Mindsensors PF Mate
- * This device is used to control Lego Power Function IR receiver
- * - * @author Michael Smith - * - */ -public class PFMate extends I2CSensor{ - public PFMateMotor A; - public PFMateMotor B; - - public static final int DEFAULT_PFMATE_ADDRESS = 0x48; - - private final static int CHANNEL_REG = 0x42; //register to control the channel the receiver is using - private final static int MOTORS_REG = 0x43; // register for motor control - private final static int OPER_A_REG = 0x44; // register for motor direction of motor A - private final static int SPEED_A_REG = 0x45; // register for speed of motor A - private final static int OPER_B_REG = 0x46; // register for motor direction of motor B - private final static int SPEED_B_REG = 0x47; // register for speed of motor B - - private byte [] buffer = new byte[1]; - - private void init(int channel) - { - setChannel(channel); - setMotor(0); - - A = new PFMateMotor(this, OPER_A_REG, SPEED_A_REG); - B = new PFMateMotor(this, OPER_B_REG, SPEED_B_REG); - - } - /** - * Constructor takes in the sensor port and the PF channel you will be using - * @param port sensor port - * @param channel PF Channel 1-4 - */ - public PFMate(I2CPort port, int channel){ - this(port, channel, DEFAULT_PFMATE_ADDRESS); - } - - /** - * Constructor takes in the sensor port and the PF channel you will be using - * @param port sensor port - * @param channel PF Channel 1-4 - * @param address I2C address of the controller - */ - public PFMate(I2CPort port, int channel, int address){ - super(port, address); - init(channel); - } - - /** - * Constructor takes in the sensor port and the PF channel you will be using - * @param port sensor port - * @param channel PF Channel 1-4 - */ - public PFMate(Port port, int channel){ - this(port, channel, DEFAULT_PFMATE_ADDRESS); - } - - /** - * Constructor takes in the sensor port and the PF channel you will be using - * @param port sensor port - * @param channel PF Channel 1-4 - * @param address I2C address of the controller - */ - public PFMate(Port port, int channel, int address){ - super(port, address, TYPE_LOWSPEED); - init(channel); - } - - /** - * Sends command to PF IR receiver to apply changes made to the registers. Call this after - * You have set speed, direction and/or channel. - */ - public void update(){ - this.sendData(0x41, (byte)0x47); - } - - /** - * Sets PF channel to use. - * @param channel 1-4 - */ - public void setChannel(int channel){ - if(channel < 1) channel = 1; - if (channel > 4) channel = 4; - sendData(CHANNEL_REG, (byte) channel); - } - - /** - * Determines which motors are to be used buy default both are activated - * @param motor 0 both, 1 motor A or 2 motor B - */ - public void setMotor(int motor){ - if(motor < 0) motor = 0; - if (motor > 2) motor = 2; - sendData(MOTORS_REG, (byte) motor); - } - - /** - * Returns the current IR channel in use by the PF Mate - * @return int 1-4 - */ - public int getChannel(){ - this.getData(CHANNEL_REG, buffer, 1); - return buffer[0]; - } - - /** - * Returns which motors are activated - * @return int 0 both, 1 motor A or 2 motor B - */ - public int getMotor(){ - this.getData(MOTORS_REG, buffer, 1); - return buffer[0]; - } -} - - diff --git a/ev3classes/src/main/java/lejos/hardware/device/PFMateMotor.java b/ev3classes/src/main/java/lejos/hardware/device/PFMateMotor.java deleted file mode 100644 index 0152a47..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/PFMateMotor.java +++ /dev/null @@ -1,141 +0,0 @@ -package lejos.hardware.device; - -import lejos.robotics.DCMotor; - -/** - * Motor class for PFMate class - * - * @author Michael Smith - * - **/ -public class PFMateMotor implements DCMotor { - private PFMate receiver; - private int operReg, speedReg; - private byte [] buffer = new byte[1]; - private final static byte FLT = 0, FORWARD = 1, BACKWARD = 2, STOP = 3; - private boolean moving = false; - - /** - * @param recever PFMate object reference - * @param operReg Motor register - * @param speedReg Speed Register - */ - PFMateMotor(PFMate recever, int operReg, int speedReg){ - this.receiver = recever; - this.operReg = operReg; - this.speedReg = speedReg; - } - - //motor operations - /** - * Floats the motor - */ - public void flt(){ - receiver.sendData(operReg, FLT); - moving = false; - } - - /** - * Runs the motor forward - * - */ - public void forward(){ - receiver.sendData(operReg, FORWARD); - receiver.sendData(0x41, (byte)0x47); - moving = true; - } - - /** - * Runs the motor backward - * - */ - public void backward(){ - receiver.sendData(operReg, BACKWARD); - receiver.sendData(0x41, (byte)0x47); - moving = true; - } - - /** - * Stops the Motor - * - */ - public void stop(){ - receiver.sendData(operReg, STOP); - receiver.sendData(0x41, (byte)0x47); - moving = false; - } - - /** - * Sets the motors speed - * @param speed 1 = 7 - */ - public void setSpeed(int speed){ - if(speed < 1) speed = 1; - if (speed > 7) speed = 7; - receiver.sendData(speedReg, (byte) speed); - receiver.sendData(0x41, (byte)0x47); - } - - /** - * returns the speed - * @return 1 - 7 - */ - public int getSpeed(){ - receiver.getData(speedReg, buffer, 1); - return buffer[0]; - } - - /** - * Determines if motor is floating this is based on what the receiver has in its registers - * @return boolean - */ - public boolean isFlt(){ - receiver.getData(operReg, buffer, 1); - if(buffer[0]== FLT) return true; - return false; - } - - /** - * Determines if motor is moving forward this is based on what the receiver has in its registers - * @return boolean - */ - public boolean isForward(){ - receiver.getData(operReg, buffer, 1); - if(buffer[0]== FORWARD) return true; - return false; - } - - /** - * Determines if motor is moving backwards this is based on what the receiver has in its registers - * @return boolean - */ - public boolean isBackward(){ - receiver.getData(operReg, buffer, 1); - if(buffer[0]== BACKWARD) return true; - return false; - } - - /** - * Determines if motor is stopped this is based on what the receiver has in its registers - * @return boolean - */ - public boolean isStop(){ - receiver.getData(operReg, buffer, 1); - if(buffer[0]== STOP) return true; - return false; - } - - public boolean isMoving() { - return moving; - } - - public void setPower(int power) - { - setSpeed((power*7)/100); - } - - public int getPower() - { - return (getSpeed()*100)/7; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/PFMotorPort.java b/ev3classes/src/main/java/lejos/hardware/device/PFMotorPort.java deleted file mode 100644 index 3fc5146..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/PFMotorPort.java +++ /dev/null @@ -1,47 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.BasicMotorPort; - -/** - * MotorPort for PF Motors using HiTechnic IRLink - * - * @author Lawrie Griffiths - * - */ -public class PFMotorPort implements BasicMotorPort { - private int channel, slot; - private IRLink link; - private static final int[] modeTranslation = {1,2,3,0}; - - public PFMotorPort(IRLink link, int channel, int slot) { - this.channel = channel; - this.slot = slot; - this.link = link; - } - - public void controlMotor(int power, int mode) { - if (mode < 1 || mode > 4) return; - link.sendPFComboDirect(channel, (slot == 0 ? modeTranslation[mode-1] : 0), (slot == 1 ? modeTranslation[mode-1] : 0)); - } - - public void setPWMMode(int mode) { - // Not implemented - } - - @Override - public void close() - { - } - - @Override - public String getName() - { - return null; - } - - @Override - public boolean setPinMode(int mode) - { - return false; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/PSPNXController.java b/ev3classes/src/main/java/lejos/hardware/device/PSPNXController.java deleted file mode 100644 index b0790e4..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/PSPNXController.java +++ /dev/null @@ -1,172 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * This class allows you to use a Sony Playstation 2 controller to - * control your robot in conjunction with the Mindsensors.com - * PSP-Nx interface. The controller has 2 analog joysticks and - * 16 buttons. See www.mindsensors.com - * - */ -/* - * DEV NOTES To Do: - * - Add listened interface? - * - */ -public class PSPNXController extends I2CSensor { - /* Send command */ - private static final byte MODE = 0x41; - - /* Mode Commands */ - private static final byte ENERGIZED = 0x45; // Power on - private static final byte DE_ENERGIZED = 0x44; // Power off - private static final byte SET_DIGITAL_MODE = 0x41; - private static final byte SET_ANALOG_MODE = 0x73; - private static final byte SET_ADPA_MODE_ON = 0x4E; - private static final byte SET_ADPA_MODE_OFF = 0x4F; - - /* Device Registers */ - /** - * BUTTON_1 and _2 combine to provide status for 16 buttons - * (8 button states per byte) - */ - private static final byte BUTTON_1 = 0x42; - private static final byte BUTTON_2 = 0x43; - private static final byte X_LEFT_JOYSTICK = 0x44; - private static final byte Y_LEFT_JOYSTICK = 0x45; - private static final byte X_RIGHT_JOYSTICK = 0x46; - private static final byte Y_RIGHT_JOYSTICK = 0x47; - - private byte[] buf = new byte[2]; - - private void init() - { - // Set proper mode (power on, etc..): - powerUp(true); - setDigitalMode(true); - } - - public PSPNXController(I2CPort port) { - this(port, DEFAULT_I2C_ADDRESS); - } - - public PSPNXController(I2CPort port, int address) { - super(port, address); - init(); - } - - public PSPNXController(Port port) { - this(port, DEFAULT_I2C_ADDRESS); - } - - public PSPNXController(Port port, int address) { - super(port, address, TYPE_LOWSPEED); - init(); - } - - /* - * Set the sensor into the specified mode. Keep track of which mode we are - * operating in. Make a note of when any distance data will become available - * - */ - private void setMode(byte mode) { - buf[0] = mode; - sendData(MODE, buf, 1); - } - - public void powerUp(boolean activate) { - if (activate) - setMode(ENERGIZED); - else - setMode(DE_ENERGIZED); - } - - /** - * Each bit in the short byte represents the boolean (pressed or - * not pressed) of a button. - * @return Data for all 16 buttons as a int array - */ - public int[] getButtons() { - int Buttons[] = new int[16]; - - getData(BUTTON_1, buf,2); - Buttons[0] = ((buf[0] >> 7) & 0x01) > 0 ? 0 : 1; - Buttons[1] = ((buf[0] >> 6) & 0x01) > 0 ? 0 : 1; - Buttons[2] = ((buf[0] >> 5) & 0x01) > 0 ? 0 : 1; - Buttons[3] = ((buf[0] >> 4) & 0x01) > 0 ? 0 : 1; - Buttons[4] = ((buf[0] >> 3) & 0x01) > 0 ? 0 : 1; - Buttons[5] = ((buf[0] >> 2) & 0x01) > 0 ? 0 : 1; - - Buttons[6] = ((buf[0] >> 1) & 0x01) > 0 ? 0 : 1; - Buttons[7] = ((buf[0] >> 0) & 0x01) > 0 ? 0 : 1; - - Buttons[8] = ((buf[1] >> 7) & 0x01) > 0 ? 0 : 1; - Buttons[9] = ((buf[1] >> 6) & 0x01) > 0 ? 0 : 1; - Buttons[10] = ((buf[1] >> 5) & 0x01) > 0 ? 0 : 1; - Buttons[11] = ((buf[1] >> 4) & 0x01) > 0 ? 0 : 1; - Buttons[12] = ((buf[1] >> 3) & 0x01) > 0 ? 0 : 1; - Buttons[13] = ((buf[1] >> 2) & 0x01) > 0 ? 0 : 1; - Buttons[14] = ((buf[1] >> 1) & 0x01) > 0 ? 0 : 1; - Buttons[15] = ((buf[1] >> 0) & 0x01) > 0 ? 0 : 1; - - return Buttons; - } - - public void setDigitalMode(boolean activate) { - if(activate) - setMode(SET_DIGITAL_MODE); - else - setMode(SET_ANALOG_MODE); - } - - public int getLeftX() { - getData(X_LEFT_JOYSTICK, buf,1); - return (((buf[0] & 0xFF) - 128) * 100 / 128); - } - - public int getLeftY() { - getData(Y_LEFT_JOYSTICK, buf,1); - return (((buf[0] & 0xFF) - 128) * 100 / 128); - } - - public int getRightX() { - getData(X_RIGHT_JOYSTICK, buf,1); - return (((buf[0] & 0xFF) - 128) * 100 / 128); - } - - public int getRightY() { - getData(Y_RIGHT_JOYSTICK, buf,1); - return (((buf[0] & 0xFF) - 128) * 100 / 128); - } - - /** - * Returns the current operating mode of the sensor. - * (put list of possible return values here:) - * - * @return -1 if error otherwise the operating mode - */ - public byte getMode() { - getData(MODE, buf,1); - return buf[0]; - } - - /** - * Use ADPA mode only if you are trying to connect more - * than one I2C sensor to a single port. - * @param activate - */ - public void setADPAMode(boolean activate) { - /* - * DEVELOPER NOTES: If all I2C sensors use the same - * adpa mode address, this method could be incorporated into - * the I2CSensor class instead. - */ - if(activate) - setMode(SET_ADPA_MODE_ON); - else - setMode(SET_ADPA_MODE_OFF); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/device/RCXLink.java b/ev3classes/src/main/java/lejos/hardware/device/RCXLink.java deleted file mode 100644 index a6bae22..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/RCXLink.java +++ /dev/null @@ -1,255 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.motor.RCXMotor; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; -import lejos.remote.rcx.Opcode; -import lejos.remote.rcx.RCXRemoteMotorPort; -import lejos.utility.Delay; - -/** - * Supports Mindsensors NRLink RCX IR adapter. - * - * @author Lawrie Griffiths - * - */ -public class RCXLink extends I2CSensor implements Opcode, IRTransmitter { - - private byte[] buf = new byte[4]; - - public RCXMotor A = new RCXMotor(new RCXRemoteMotorPort(this,0)); - public RCXMotor B = new RCXMotor(new RCXRemoteMotorPort(this,1)); - public RCXMotor C = new RCXMotor(new RCXRemoteMotorPort(this,2)); - - private final static byte SLOW_SPEED = 0x44; // Default 2400 baud - private final static byte FLUSH = 0x46; // Flush the FIFO buffer - private final static byte HIGH_SPEED = 0x48; // 4800 baudprivate final static byte LONG_RANGE = 0x4C; - private final static byte SHORT_RANGE = 0x53; - private final static byte LONG_RANGE = 0x4c; - private final static byte TRANSMIT_RAW_MACRO = 0x55; // Transmit Unassembled raw macro data; - private final static byte COMMAND = 0x41; - private final static byte RUN = 0x52; - private final static byte ARPA_ON = 0x4E; - private final static byte ARPA_OFF = 0x4F; - private final static byte STATUS_REG = 0x41; - private final static byte RX_DATA_LEN = 0x40; - private final static byte TX_DATA_LEN = 0x40; - private final static byte RX_DATA = 0x42; - private final static byte TX_DATA = 0x42; - - // ROM Macro Definitions: - public final static byte SHORT_RANGE_IR = 0x01; - public final static byte LONG_RANGE_IR = 0x04; - public final static byte POWER_OFF_RCX = 0x07; - public final static byte RUN_PROGRAM_1 = 0x09; - public final static byte RUN_PROGRAM_2 = 0x0D; - public final static byte RUN_PROGRAM_3 = 0x11; - public final static byte RUN_PROGRAM_4 = 0x15; - public final static byte RUN_PROGRAM_5 = 0x19; - public final static byte STOP_ALL_PROGRAMS = 0x1D; - public final static byte MOTOR_A_FORWARD = 0x21; - public final static byte MOTOR_A_REVERSED = 0x25; - public final static byte MOTOR_B_FORWARD = 0x29; - public final static byte MOTOR_B_REVERSED = 0x2D; - public final static byte MOTOR_C_FORWARD = 0x31; - public final static byte MOTOR_C_REVERSED = 0x35; - /** - * NOTE: The BEEP macro is unreliable. - * It works once, and then needs another command executed - * before it works again. - */ - public final static byte BEEP = 0x39; - - public final static int EEPROM_BUFFER = 0x78; - public final static int DELAY = 10; - - public RCXLink(I2CPort port) { - super(port); - } - - public RCXLink(Port port) { - super(port); - } - - public void runMacro(int addr) { - buf[0] = RUN; - buf[1] = (byte) addr; - - sendData(COMMAND, buf, 2); - } - - public void beep() { - runMacro(BEEP); - } - - public void runProgram(int programNumber) { - runMacro(RUN_PROGRAM_1 + ((programNumber-1)*4)); - } - - public void forwardStep(int id) { // RCX Remote Command - runMacro(MOTOR_A_FORWARD + (id*8)); - } - - public void backwardStep(int id) { // RCX Remote Command - runMacro(MOTOR_A_REVERSED + (id*8)); - } - - public void setRCXRangeShort() { - runMacro(SHORT_RANGE_IR); - } - - public void setRCXRangeLong() { - runMacro(LONG_RANGE_IR); - } - - public void powerOff() { - runMacro(POWER_OFF_RCX); - } - - public void stopAllPrograms() { - runMacro(STOP_ALL_PROGRAMS); - } - - public void flush() { - sendData(COMMAND, FLUSH); - } - - public void setDefaultSpeed() { - sendData(COMMAND, SLOW_SPEED); - } - - public void setHighSpeed() { - sendData(COMMAND, HIGH_SPEED); - } - - public void setRangeLong() { - sendData(COMMAND, LONG_RANGE); - } - - public void setRangeShort() { - sendData(COMMAND, SHORT_RANGE); - } - - public void setAPDAOn() { - sendData(COMMAND, ARPA_ON); - } - - public void setAPDAOff() { - - sendData(COMMAND, ARPA_OFF); - } - - public void defineMacro(int addr, byte[] macro) { - sendData((byte) addr,(byte) macro.length); - sleep(); - sendData((byte) addr+1, macro, macro.length); - } - - public int getStatus() { - getData(STATUS_REG, buf, 1); - return buf[0] & 0xFF; - } - - public int bytesAvailable() { - getData(RX_DATA_LEN, buf, 1); - return buf[0] & 0xFF; - } - - public void ping() { - buf[0] = OPCODE_ALIVE; - defineAndRun(buf,1); - } - - public void sendF7(int msg) { - buf[0] = OPCODE_SET_MESSAGE; - buf[1] = (byte) (msg & 0xFF); - defineAndRun(buf,2); - } - - public void sendPacket(byte [] packet) { - defineAndRun(packet, packet.length); - } - - public void sendRemoteCommand(int msg) { - buf[0] = OPCODE_REMOTE_COMMAND; - buf[1] = (byte) (msg >> 8); - buf[2] = (byte) (msg & 0xFF); - defineAndRun(buf,3); - } - - public void setMotorPower(int id, int power) { - buf[0] = OPCODE_SET_MOTOR_POWER; - buf[1] = (byte) (1 << id); - buf[2] = 2; - buf[3] = (byte) power; - defineMacro(EEPROM_BUFFER, buf); // Bug: sendData cannot send more than 3 bytes - sleep(); - sendData(EEPROM_BUFFER+4, (byte) power); - sleep(); - runMacro(EEPROM_BUFFER); - } - - public void stopMotor(int id) { - buf[0] = OPCODE_SET_MOTOR_ON_OFF; - buf[1] = (byte) ((1 << id) | 0x40); - defineAndRun(buf,2); - } - - public void startMotor(int id) { - buf[0] = OPCODE_SET_MOTOR_ON_OFF; - buf[1] = (byte) ((1 << id) | 0x80); - defineAndRun(buf,2); - } - - public void fltMotor(int id) { - buf[0] = OPCODE_SET_MOTOR_ON_OFF; - buf[1] = (byte) (1 << id); - defineAndRun(buf,2); - } - - public void forward(int id) { - buf[0] = OPCODE_SET_MOTOR_DIRECTION; - buf[1] = (byte) ((1 << id) | 0x80); - defineAndRun(buf,2); - } - - public void backward(int id) { - buf[0] = OPCODE_SET_MOTOR_DIRECTION; - buf[1] = (byte) (1 << id); - defineAndRun(buf,2); - } - - public void setRawMode() { - sendData(COMMAND, TRANSMIT_RAW_MACRO); - } - - public void sendBytes(byte[] data, int len) { - sendData(TX_DATA,data,len); - sleep(); - sendData(TX_DATA_LEN, (byte) len); - } - - public int readBytes(byte [] data) { - getData(RX_DATA_LEN,buf,1); - int numBytes = buf[0]; - if (numBytes > 0) { - if (numBytes > data.length) numBytes = data.length; - sleep(); - getData(RX_DATA,data,numBytes); - } - return numBytes; - } - - private void sleep() { - Delay.msDelay(DELAY); - } - - public void defineAndRun(byte[] macro, int len) { - sendData(EEPROM_BUFFER,(byte) len); - sleep(); - sendData(EEPROM_BUFFER+1, macro, len); - sleep(); - runMacro(EEPROM_BUFFER); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/RCXMotorMultiplexer.java b/ev3classes/src/main/java/lejos/hardware/device/RCXMotorMultiplexer.java deleted file mode 100644 index 1aeffb6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/RCXMotorMultiplexer.java +++ /dev/null @@ -1,68 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.motor.RCXMotor; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * Supports the mindsensors RCX Motor Multiplexer - * - * @author Lawrie Griffiths - * - */ -public class RCXMotorMultiplexer extends I2CSensor { - private byte[] buf = new byte[2]; - - public static final int DEFAULT_RCXMMUX_ADDRESS = 0xb4; - - public RCXMotor A = new RCXMotor(new RCXPlexedMotorPort(this,0)); - public RCXMotor B = new RCXMotor(new RCXPlexedMotorPort(this,1)); - public RCXMotor C = new RCXMotor(new RCXPlexedMotorPort(this,2)); - public RCXMotor D = new RCXMotor(new RCXPlexedMotorPort(this,3)); - - - public RCXMotorMultiplexer(I2CPort port) { - this(port, DEFAULT_RCXMMUX_ADDRESS); - - } - - public RCXMotorMultiplexer(I2CPort port, int address) { - super(port, address); - } - - public RCXMotorMultiplexer(Port port) { - this(port, DEFAULT_RCXMMUX_ADDRESS); - - } - - public RCXMotorMultiplexer(Port port, int address) { - super(port, address, TYPE_LOWSPEED_9V); - } - - public void setSpeed(int speed, int id) { - buf[0] = (byte) speed; - sendData(0x43 + (id*2), buf, 1); - } - - public int getSpeed(int id) { - getData(0x43 + (id*2), buf, 1); - return buf[0] & 0xFF; - } - - public void sendCommand(int id, int direction, int speed) { - buf[0] = (byte) direction; - buf[1] = (byte) speed; - sendData(0x42 + (id*2), buf, 2); - } - - public void setDirection(int direction, int id) { - buf[0] = (byte) direction; - sendData(0x42 + (id*2), buf, 1); - } - - public int getDirection(int id) { - getData(0x42 + (id*2), buf, 1); - return buf[0] & 0xFF; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/RCXPlexedMotorPort.java b/ev3classes/src/main/java/lejos/hardware/device/RCXPlexedMotorPort.java deleted file mode 100644 index 6eefaf5..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/RCXPlexedMotorPort.java +++ /dev/null @@ -1,51 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.BasicMotorPort; - -/** - * Supports a motor connected to the Mindsensors RCX Motor Multiplexer - * - * @author Lawrie Griffiths - * - */ -public class RCXPlexedMotorPort implements BasicMotorPort { - private RCXMotorMultiplexer plex; - private int id; - - public RCXPlexedMotorPort(RCXMotorMultiplexer plex, int id) { - this.plex = plex; - this.id = id; - } - - public void controlMotor(int power, int mode) { - int mmMode = mode; - if (mmMode == BasicMotorPort.FLOAT) mmMode = 0; // float - int mmPower = (int) (power * 2.55f); - if (mmMode == BasicMotorPort.STOP) { - mmPower = 255; // Maximum breaking - } - plex.sendCommand(id, mmMode, mmPower); - } - - public void setPWMMode(int mode) { - // Not implemented - } - - @Override - public void close() - { - // not implemented - } - - @Override - public String getName() - { - return null; - } - - @Override - public boolean setPinMode(int mode) - { - return false; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/RCXSensorMultiplexer.java b/ev3classes/src/main/java/lejos/hardware/device/RCXSensorMultiplexer.java deleted file mode 100644 index cfd06aa..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/RCXSensorMultiplexer.java +++ /dev/null @@ -1,98 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * Supports Mindsensors RXMux
- * This sensor allows you to connect up to four RCX type sensors toa single port. - * Be aware that the sensor does not track the ticks of the rotation sensor when - * the port is not selected. - * - * @author Michael Smith - * - */ -public class RCXSensorMultiplexer extends I2CSensor{ - private final static byte CONTROL = 0x00; - private final static int CHANNEL1 = 0xfe; - private final static int CHANNEL2 = 0xfd; - private final static int CHANNEL3 = 0xfb; - private final static int CHANNEL4 = 0xf7; - private final static int ALLOFF = 0xFF; - - public static final int DEFAULT_RCXSMUX_ADDRESS = 0x7e; - - /** - * - * @param port NXT Sensor port - */ - public RCXSensorMultiplexer(I2CPort port){ - this(port, DEFAULT_RCXSMUX_ADDRESS); - } - - /** - * - * @param port NXT Sensor port - * @param address I2C address - */ - public RCXSensorMultiplexer(I2CPort port, int address){ - super(port, address); - } - /** - * - * @param port NXT Sensor port - */ - public RCXSensorMultiplexer(Port port){ - this(port, DEFAULT_RCXSMUX_ADDRESS); - } - - /** - * - * @param port NXT Sensor port - * @param address I2C address - */ - public RCXSensorMultiplexer(Port port, int address){ - super(port, address, TYPE_LOWSPEED); - } - - /** - * Selects channel one - * - */ - public void setChannelOne(){ - sendData(CONTROL, (byte)CHANNEL1); - } - - /** - * Selects channel two - * - */ - public void setChannelTwo(){ - sendData(CONTROL, (byte)CHANNEL2); - } - - /** - * Selects channel three - * - */ - public void setChannelThree(){ - sendData(CONTROL, (byte)CHANNEL3); - } - - /** - * Selects channel four - * - */ - public void setChannelFour(){ - sendData(CONTROL, (byte)CHANNEL4); - } - - /** - * Turns off all channels - * - */ - public void allChannelsOff(){ - sendData(CONTROL, (byte)ALLOFF); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/SensorMux.java b/ev3classes/src/main/java/lejos/hardware/device/SensorMux.java deleted file mode 100644 index fa1faf2..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/SensorMux.java +++ /dev/null @@ -1,150 +0,0 @@ -package lejos.hardware.device; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/* - * WARNING: THIS CLASS IS SHARED BETWEEN THE classes AND pccomms PROJECTS. - * DO NOT EDIT THE VERSION IN pccomms AS IT WILL BE OVERWRITTEN WHEN THE PROJECT IS BUILT. - */ - -/** - * @author 3DGamer (LeJOS Forum User) - * @author Juan Antonio Brenha Moral - * @author Xander Soldaat - */ -public class SensorMux extends I2CSensor { - - private final int STATUS_BATTERY_BIT = 1; - private final byte digitalRegisters[] = {0x40,0x50,0x60,0x70}; - private final byte analogRegisters[] = {0x36,0x38,0x3A,0x3C}; - - /** - * Constructor - * @param port the port - */ - public SensorMux(I2CPort port) { - super(port, 0x10); - } - - /** - * Constructor - * @param port the port - */ - public SensorMux(Port port) { - super(port, 0x10, TYPE_LOWSPEED_9V); - } - - /** - * Return the type - * @return the type - */ - public int getType() { - byte[] buf = new byte[1]; - getData(0x23,buf,1); - return buf[0] & 0xff; - } - - /** - * Method used to get if battery status is low. - * @return true if the battery is low, else false - */ - public boolean isBatteryLow(){ - byte[] buf = new byte[1]; - getData(0x21,buf,1); - return ((buf[0]&STATUS_BATTERY_BIT)!=0); - } - - /** - * This method return the value from a digital sensor. - * Currently, SMux supports Ultrasonic Sensors - * - * @param channel the index of the channel - * @return the digital value - */ - private int getDigitalValue(int channel){ - byte[] buf = new byte[1]; - byte register = digitalRegisters[channel-1]; - getData(register,buf,1); - int digitalValue = buf[0] & 0xff; - return digitalValue; - } - - /** - * This method return the value from a analogic sensor. - * Currently, SMux supports Touch sensor and Sound sensor - * - * @param channel the index of the channel - * @return the analog value - */ - private int getAnalogValue(int channel){ - byte[] buf = new byte[1]; - byte register = analogRegisters[channel-1]; - getData(register,buf,1); - int analogValue = buf[0] & 0xff; - return analogValue; - } - - /** - * This method is necessary to execute to connect sensors on it - */ - public void configurate(){ - - //Set the SMUX in halted mode: 0x10 0x20 0x00 - sendData(0x20, (byte)0x00); - - // Wait 50 ms for SMUX to clean up - try{Thread.sleep(50);}catch(Exception e){} - - //# Send auto-scan command: 0x10 0x20 0x01 - sendData(0x20, (byte)0x01); - - //# wait 500ms for auto-scan to complete - try{Thread.sleep(600);}catch(Exception e){} - - //# Set the SMUX in normal mode: 0x10 0x20 0x02 - sendData(0x20, (byte)0x02); - } - - /** - * Method used to use a US with the sensor and get the distances - * @param channel the index of the channel - * @return the distance - */ - public int getDistance(int channel){ - int distance = 0; - distance = getDigitalValue(channel); - return distance; - } - - /** - * Method used to manage a Touch Sensor - * - * @param channel the index of the channel - * @return true if the sensor is presed, else false - */ - public int isPressed(int channel){ - int pressed = 0; - pressed = getAnalogValue(channel); - if(pressed == 255){ - pressed = 0; - }else{ - pressed = 1; - } - return pressed; - } - - /** - * Method used to receive data from a Sound Sensor - * - * @param channel the index of the channel - * @return the value - */ - public int readValue(int channel){ - int value = 0; - value = getAnalogValue(channel); - value = ((1023 - value) * 100/ 1023); - return value; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/TouchMUX.java b/ev3classes/src/main/java/lejos/hardware/device/TouchMUX.java deleted file mode 100644 index 1b99cfd..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/TouchMUX.java +++ /dev/null @@ -1,189 +0,0 @@ -package lejos.hardware.device; - -import lejos.robotics.Touch; -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.AnalogSensor; -import lejos.hardware.sensor.SensorConstants; - -/** - * Interface for the Mindsensors Touch Multiplexer. - * This device allows up to three touch sensors to be attached to a single NXT - * sensor port. - * - * @author Andy - * - */ -public class TouchMUX extends AnalogSensor { - /** number of touch sensors supported by this device **/ - public static final int NUMBER_OF_SENSORS = 3; - /** Bit ID returned by readSensors when sensor T1 is pressed **/ - public static final int ID_T1 = (1 << 0); - /** Bit ID returned by readSensors when sensor T1 is pressed **/ - public static final int ID_T2 = (1 << 1); - /** Bit ID returned by readSensors when sensor T1 is pressed **/ - public static final int ID_T3 = (1 << 2); - - private class MuxTouchSensor implements Touch - { - private int id; - - /** - * Create an object to represent one touch sensor attached to the - * multiplexer. - * @param touchId The id of this sensor. - */ - MuxTouchSensor(int touchId) - { - id = touchId; - } - - /** - * Check if the sensor is pressed. - * @return true if sensor is pressed, false otherwise. - */ - public boolean isPressed() - { - return (readSensors() & id) != 0; - } - } - - - /** Instance for the touch sensor connected to port T1 **/ - public final Touch T1 = new MuxTouchSensor(ID_T1); - /** Instance for the touch sensor connected to port T2 **/ - public final Touch T2 = new MuxTouchSensor(ID_T2); - /** Instance for the touch sensor connected to port T3 **/ - public final Touch T3 = new MuxTouchSensor(ID_T3); - - /** - * Create a object to provide access to a touch sensor multiplexer - * @param port The NXT sensor port to which the multiplexer is attached - */ - public TouchMUX(AnalogPort port) - { - super(port); - //port.setTypeAndMode(SensorConstants.TYPE_CUSTOM, SensorConstants.MODE_RAW); - } - - /** - * Create a object to provide access to a touch sensor multiplexer - * @param port The NXT sensor port to which the multiplexer is attached - */ - public TouchMUX(Port port) - { - super(port); - this.port.setTypeAndMode(SensorConstants.TYPE_CUSTOM, SensorConstants.MODE_RAW); - } - - /** - * Return a Touch interface providing access to the sensor specified by the - * given id. - * @param id a number between 0..{@link #NUMBER_OF_SENSORS}-1 - * @return the requested Touch interface - */ - public synchronized Touch getInstance(int id) - { - switch(id) - { - case 0: - return T1; - case 1: - return T2; - case 2: - return T3; - default: - throw new IllegalArgumentException("no such touch sensor port"); - } - } - - /* - * Following values provide High and Low limits for the various - * sensor combinations, as supplied by Mindsensors. - * Note however that these values assume the RAW readings obtained when the - * sensor type is set to be a Lego light sensor. With the Lego firmware this - * is not the actual A/D reading instead it is a value correct for the offset - * and range of the sensor in the following way... - * MIN_LS_READING = 200 - * MAX_LS_READING = 900 - * legoVal = MAX_AD_RAW - ((rawVal-MIN_LS_READING)*100)/((MAX_LS_READING - MIN_LS_READING)*100)/MAX_AD_RAW - * which gives - * legoVal = MAX_AD_RAW - ((rawVal - MIN_LS_READING)*MAX_AD_RAW)/(MAX_LS_READING - MIN_LS_READING) - * To correct the values used we must adjust them as follows... - * lejosVal = (MAX_AD_RAW - legoVal) * (MAX_LS_READING - MIN_LS_READING))/MAX_AD_RAW + MIN_LS_READING - * The actual values used below have been corrected in this way..... - * Note also that the Hi/Lo of the test has been changed because the values now drop in value.. - * Original values: - private static final int L1 = 60; - private static final int H1 = 160; - private static final int L2 = 210; - private static final int H2 = 290; - private static final int L3 = 500; - private static final int H3 = 599; - private static final int L12 = 370; - private static final int H12 = 460; - private static final int L13 = 600; - private static final int H13 = 658; - private static final int L23 = 659; - private static final int H23 = 723; - private static final int L123 = 724; - private static final int H123 = 800; - * Adjusted values: - */ - private static final int H1 = 859; - private static final int L1 = 791; - private static final int H2 = 756; - private static final int L2 = 701; - private static final int H3 = 558; - private static final int L3 = 490; - private static final int H12 = 647; - private static final int L12 = 585; - private static final int H13 = 489; - private static final int L13 = 450; - private static final int H23 = 449; - private static final int L23 = 405; - private static final int H123 = 404; - private static final int L123 = 352; - - /** - * Read the touch multiplexer and return a bit mask showing which sensors - * are currently pressed. Returns ID_T1 if T1 is pressed, ID_T2 if T2 is - * pressed and ID_T3 id T3 is pressed. If more then one sensor is pressed - * the return will be an or of the values. - * @return bit mask showing which sensor buttons are pressed. - */ - public int readSensors() - { - int ret; - int val = NXTRawIntValue(port.getPin1()); - /* - * Note the following code can be used to correct the RAW value to be - * the same as the RAW value for a Lego light sensor. Allowing the use - * of the original Mindsensor constants. - if (val > 200) - val -= 200; - else - val = 0; - val = (val*100)/68; - val = 1023 - val - */ - if (L1 <= val && val < H1) - ret = ID_T1; - else if (L2 <= val && val < H2) - ret = ID_T2; - else if (L3 <= val && val < H3) - ret = ID_T3; - else if (L12 <= val && val < H12) - ret = ID_T1|ID_T2; - else if (L13 <= val && val < H13) - ret = ID_T1|ID_T3; - else if (L23 <= val && val < H23) - ret = ID_T2|ID_T3; - else if (L123 <= val && val < H123) - ret = ID_T1|ID_T2|ID_T3; - else - ret = 0; - return ret; - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/UART.java b/ev3classes/src/main/java/lejos/hardware/device/UART.java deleted file mode 100644 index 515dbc1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/UART.java +++ /dev/null @@ -1,168 +0,0 @@ -package lejos.hardware.device; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.hardware.sensor.EV3SensorConstants; -import lejos.utility.Delay; - -/** - * This class provides low level access to a UART device. - * @author andy - * - */ -public class UART implements Closeable -{ - /** - * internal class that provides an InputStream interface to - * a UART - * @author andy - * - */ - protected class UARTInputStream extends InputStream - { - protected byte[] buffer = new byte[1]; - - @Override - public int read() throws IOException - { - while(port.rawRead(buffer, 0, 1) == 0) - Delay.msDelay(1); - return buffer[0]; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException - { - int total = len; - if (len == 0) return 0; - for(;;) - { - int ret = port.rawRead(b, off, len); - len -= ret; - if (len <= 0) - return total; - off += ret; - Delay.msDelay(1); - } - } - - } - - /** - * internal class that provides an OutputStream interface to - * a UART - * @author andy - * - */ - protected class UARTOutputStream extends OutputStream - { - protected byte[] buffer = new byte[1]; - - @Override - public void write(int arg0) throws IOException - { - buffer[0] = (byte)arg0; - while(port.rawWrite(buffer, 0, 1) == 0) - Delay.msDelay(1); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException - { - if (len == 0) - return; - for(;;) - { - int written = port.rawWrite(b, off, len); - len -= written; - if (len <= 0) - return; - off += written; - Delay.msDelay(1); - } - } - } - - protected UARTPort port; - protected InputStream inputStream; - protected OutputStream outputStream; - - /** - * Create a UART device attached to the specified port. - * @param port - */ - public UART(Port port) - { - this.port = port.open(UARTPort.class); - this.port.setMode(UARTPort.UART_RAW_MODE); - } - - @Override - public void close() - { - port.close(); - } - - /** - * Set the bit rate to be used by the UART - * @param rate - */ - public void setBitRate(int rate) - { - port.setBitRate(rate); - } - - /** - * Read bytes from the device. The read is non blocking and will return - * a count of 0 if no bytes are available to read. - * @param buffer buffer to read the bytes into - * @param offset first position that bytes will be read into - * @param len maximum number of bytes to read - * @return actual number of bytes read - */ - public int read(byte []buffer, int offset, int len) - { - return port.rawRead(buffer, offset, len); - } - - /** - * Write bytes to the device. The write is non blocking and will return 0 if it - * is not possible to write to the device. - * @param buffer buffer to write from - * @param offset offset of first byte to be written - * @param len number of bytes to try and write - * @return number of bytes actually written - */ - public int write(byte []buffer, int offset, int len) - { - return port.rawWrite(buffer, offset, len); - } - - /** - * Return the InputStream associated with this device. - * @return the InputStream that can be used to read from the UART - */ - public synchronized InputStream getInputStream() - { - if (inputStream == null) - inputStream = new UARTInputStream(); - return inputStream; - } - - /** - * Return the OutputStream associated with this device. - * @return the OutputStream that can be used to write to the UART - */ - public synchronized OutputStream getOutputStream() - { - if (outputStream == null) - outputStream = new UARTOutputStream(); - return outputStream; - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/package-info.java b/ev3classes/src/main/java/lejos/hardware/device/package-info.java deleted file mode 100644 index e5801c8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Support for EV3 third-party devices - * - */ -package lejos.hardware.device; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixControllerFactory.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixControllerFactory.java deleted file mode 100644 index 357be54..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixControllerFactory.java +++ /dev/null @@ -1,136 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.hardware.port.Port; -import lejos.hardware.sensor.I2CSensor; - -/** - * HiTechnic Tetrix Motor and Servo Controller factory class used to provide Motor and Servo controller abstractions. - * These are then used - * to obtain motor and servo instances respectively. These abstraction classes are TetrixMotorController and - * TetrixServoController. - *

- * Motor and servo controllers are enumerated starting at the controller connected to one of the NXT's sensor ports and then - * working outwards along the daisy chain. 4 controllers can be daisy-chained, with a mixture of servo and/or motor controllers. - * No other sensors can be connected to the daisy-chain. - * - *

Code Example:
- *

- * // Instantiate the factory and get a Motor and servo controller. We assume that there is one of 
- * // each daisy-chained.
- * TetrixControllerFactory cf = new TetrixControllerFactory(SensorPort.S1);
- * TetrixMotorController mc = cf.newMotorController();
- * TetrixServoController sc = cf.newServoController();
- * 
- * // Display the voltage from the motor controller
- * System.out.println("v=" + mc.getVoltage());'
- * 
- * // Get an encoder motor instance. The physical motor (with encoder) is connected to the Motor 2 terminals on the controller
- * TetrixEncoderMotor mot1 = mc.getEncoderMotor(TetrixMotorController.MOTOR_2);
- * 
- * // Start the motor
- * mot1.forward();
- * 
- * - * @author Kirk P. Thompson - * @see TetrixMotorController - * @see TetrixServoController - */ -public class TetrixControllerFactory { - /** - * Position 1 (nearest to the NXT) in the daisy chain. Use this if only one controller. - */ - public static final int DAISY_CHAIN_POSITION_1 = 2; - /** - * Position 2 in the daisy chain. - */ - public static final int DAISY_CHAIN_POSITION_2 = 4; - /** - * Position 3 in the daisy chain. - */ - public static final int DAISY_CHAIN_POSITION_3 = 6; - /** - * Position 3 (furthest from the NXT)in the daisy chain. - */ - public static final int DAISY_CHAIN_POSITION_4 = 8; - - private static final int MAX_CHAINED_CONTROLLERS=4; - static final String TETRIX_VENDOR_ID = "HiTechnc"; - static final String TETRIX_MOTORCON_PRODUCT_ID = "MotorCon"; - static final String TETRIX_SERVOCON_PRODUCT_ID = "ServoCon"; - - private int currentMotorIndex=0; - private int currentServoIndex=0; - private Port port; - private Finder finder; - - /** - * Instantiate a TetrixControllerFactory using the specified NXT sensor port. - * @param port The NXT sensor port the Tetrix controller is connected to - */ - public TetrixControllerFactory(Port port){ - this.port=port; - finder = new Finder(port); - } - - private class Finder extends I2CSensor { - Finder(Port port) { - super(port); - } - - /** - * @param i where to start searching index-wise - * @param product the product ID string - * @return the index the product ID was found. -1 if not found or outside MAX_CHAINED_CONTROLLERS bounds - */ - private int findProduct(int i, String product){ - if (i<0 || i>=MAX_CHAINED_CONTROLLERS) return -1; - for (;i - * Successive controllers in a daisy-chain logically go "outwards" from the controller closest to the NXT as #1 to #4 for each controller - * in the chain. Once a specific, logical controller has been retrieved using this method, it cannot be retrieved again. - *

- * A combination of Servo and Motor controllers can be daisy-chained. - * @return The next available TetrixMotorController instance. - * @throws IllegalStateException If no more motor controllers can be returned. If there are no motor controllers - * in the daisy-chain, this exception is also thrown. - * @see #newServoController - */ - public TetrixMotorController newMotorController() - { - this.currentMotorIndex = finder.findProduct(this.currentMotorIndex, TETRIX_MOTORCON_PRODUCT_ID); - if (this.currentMotorIndex<0) throw new IllegalStateException("no motor controllers available"); - TetrixMotorController mc = new TetrixMotorController(finder.getPort(), (this.currentMotorIndex + 1) * 2); - this.currentMotorIndex++; - return mc; - } - - /** - * Get the next available Tetrix Servo controller. Motor controllers in the daisy-chain (if any) are skipped in the search. - *

- * Successive controllers in a daisy-chain logically go "outwards" from the controller closest to the NXT as #1 to #4 for each controller - * in the chain. Once a specific, logical controller has been retrieved using this method, it cannot be retrieved again. - *

- * A combination of Servo and Motor controllers can be daisy-chained. - * @return The next available TetrixServoController instance. - * @throws IllegalStateException If no more servo controllers can be returned. If there are no servo controllers - * in the daisy-chain, this exception is also thrown. - * @see #newMotorController - */ - public TetrixServoController newServoController() - { - this.currentServoIndex = finder.findProduct(this.currentServoIndex, TETRIX_SERVOCON_PRODUCT_ID); - if (this.currentServoIndex<0) throw new IllegalStateException("no servo controllers available"); - TetrixServoController sc = new TetrixServoController(finder.getPort(), (this.currentServoIndex + 1) * 2); - this.currentServoIndex++; - return sc; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixEncoderMotor.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixEncoderMotor.java deleted file mode 100644 index 1a3737a..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixEncoderMotor.java +++ /dev/null @@ -1,84 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.robotics.Encoder; -import lejos.utility.Delay; - - -/** - * Tetrix DC motor abstraction with encoder support. The Tetrix motor must have an encoder installed and connected to - * the controller for the methods in this class to work. If an encoder is not installed, use the {@link TetrixMotor} - * class instead. - *

Use {@link TetrixMotorController#getEncoderMotor} to retrieve a TetrixEncoderMotor instance. - * - * @author Kirk P. Thompson - */ -public class TetrixEncoderMotor extends TetrixMotor implements Encoder{ - TetrixEncoderMotor(TetrixMotorController mc, int channel) { - super(mc, channel); - } - - public int getTachoCount() { - return (int)(mc.doCommand(TetrixMotorController.CMD_GETTACHO, 0, channel) * .25); - } - - /** - * Reset the the tachometer count. Calling this method will stop any current motor action. This is imposed by the HiTechic - * Motor Controller firmware. - */ - public synchronized void resetTachoCount() { - mc.doCommand(TetrixMotorController.CMD_RESETTACHO, 0, channel); - } - - synchronized void waitRotateComplete() { - while (isMoving()) { - Delay.msDelay(50); - } - } - - /** - * Rotate by the requested number of degrees with option for wait until completion or immediate return where the motor - * completes its rotation asynchronously. - * - * @param degrees number of degrees to rotate relative to the current position. - * @param immediateReturn if true, do not wait for the move to complete. false will block - * until the rotation completes. - */ - public void rotate(int degrees, boolean immediateReturn){ - mc.doCommand(TetrixMotorController.CMD_ROTATE, degrees, channel); - if (!immediateReturn) mc.waitRotateComplete(channel); - } - - /** - * Rotate to the target angle with option for wait until completion or immediate return where the motor - * completes its rotation asynchronously. - * - * @param limitAngle Angle [in degrees] to rotate to. - * @param immediateReturn if true, do not wait for the move to complete. false will block - * until the rotation completes. - */ - public void rotateTo(int limitAngle, boolean immediateReturn){ - mc.doCommand(TetrixMotorController.CMD_ROTATE_TO, limitAngle, channel); - if (!immediateReturn) mc.waitRotateComplete(channel); - } - - /** - * Return the last angle that this motor was rotating to via one of the rotate methods. - * @return angle in degrees - */ - public int getLimitAngle() { - return mc.doCommand(TetrixMotorController.CMD_GETLIMITANGLE, 0, channel); - } - - /** - * Disable or Enable internal motor controller speed regulation. Setting this to true will cause - * the motor controller firmware to adjust the motor power to compensate for changing loads in order to maintain - * a constant motor speed. Default at instantiation is false. - * - * @param regulate true to enable regulation, false otherwise. - */ - public void setRegulate(boolean regulate){ - int operand=TetrixMotorController.MOTPARAM_OP_FALSE; - if (regulate) operand=TetrixMotorController.MOTPARAM_OP_TRUE; - mc.doCommand(TetrixMotorController.CMD_SETREGULATE, operand, channel); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotor.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotor.java deleted file mode 100644 index 9f21cb1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotor.java +++ /dev/null @@ -1,70 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.robotics.DCMotor; - -/** - * Tetrix basic DC motor abstraction without encoder support. The default power at instantiation is 100%. - *

Use {@link TetrixMotorController#getBasicMotor} to retrieve a TetrixMotor instance. - * - * @author Kirk P. Thompson - */ -public class TetrixMotor implements DCMotor{ - TetrixMotorController mc; - int channel; - - TetrixMotor(TetrixMotorController mc, int channel) { - this.mc=mc; - this.channel=channel; - setPower(100); - } - - public void setPower(int power) { - power=Math.abs(power); - if (power>100) power=100; - mc.doCommand(TetrixMotorController.CMD_SETPOWER, power, channel); - } - - public int getPower() { - return mc.doCommand(TetrixMotorController.CMD_GETPOWER, 0, channel); - } - - public void forward() { - mc.doCommand(TetrixMotorController.CMD_FORWARD, 0, channel); - } - - public void backward() { - mc.doCommand(TetrixMotorController.CMD_BACKWARD, 0, channel); - } - - public void stop() { - mc.doCommand(TetrixMotorController.CMD_STOP, 0, channel); - } - - public void flt() { - mc.doCommand(TetrixMotorController.CMD_FLT, 0, channel); - } - - /** - * Return true if the motor is moving. Note that this method reports based on the current control - * state (i.e. commanded to move) and not if the motor is actually moving. This means a motor may be stalled but this - * method would return true. - * - * @return true if the motor is executing a movement command, false if stopped. - */ - public boolean isMoving() { - return TetrixMotorController.MOTPARAM_OP_TRUE==mc.doCommand(TetrixMotorController.CMD_ISMOVING, 0, channel); - } - - /** - * Used to alter the forward/reverse direction mapping for the motor output. This is primarily intended to - * harmonize the forward and reverse directions for motors on opposite sides of a skid-steer chassis. - *

- * Changes to this setting take effect on the next motor command. - * @param reverse true to reverse direction mapping for this motor - */ - public void setReverse(boolean reverse) { - int op=TetrixMotorController.MOTPARAM_OP_FALSE; - if (reverse) op=TetrixMotorController.MOTPARAM_OP_TRUE; - mc.doCommand(TetrixMotorController.CMD_SETREVERSE, op, channel); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotorController.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotorController.java deleted file mode 100644 index 8847744..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixMotorController.java +++ /dev/null @@ -1,584 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.sensor.I2CSensor; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - - -/** - * HiTechnic Tetrix Motor Controller abstraction. Provides TetrixMotor and TetrixEncoderMotor instances - * which are used to control the Tetrix motors. - *

- * Use {@link TetrixControllerFactory#newMotorController} to retrieve a TetrixMotorController instance. - * - * @see lejos.hardware.device.tetrix.TetrixControllerFactory - * @see lejos.hardware.device.tetrix.TetrixMotor - * @see lejos.hardware.device.tetrix.TetrixEncoderMotor - * @author Kirk P. Thompson - */ -public class TetrixMotorController extends I2CSensor { - /** Represents Motor 1 as indicated on the controller - */ - public static final int MOTOR_1 = 0; - /** Represents Motor 2 as indicated on the controller - */ - public static final int MOTOR_2 = 1; - - private static final int CHANNELS = 2; - private static final int KEEPALIVE_PING_INTERVAL = 2450; - - static final int CMD_FORWARD = 0; - static final int CMD_BACKWARD = 1; - static final int CMD_FLT = 2; - static final int CMD_STOP = 3; - static final int CMD_SETPOWER = 4; - static final int CMD_ROTATE = 5; - static final int CMD_ROTATE_TO = 6; - static final int CMD_GETPOWER = 7; - static final int CMD_RESETTACHO = 8; - static final int CMD_SETREVERSE = 10; - static final int CMD_ISMOVING = 11; - static final int CMD_SETREGULATE = 12; - static final int CMD_GETTACHO = 13; - static final int CMD_GETSPEED = 14; - static final int CMD_GETLIMITANGLE = 15; - - int[] motorState = {STATE_STOPPED, STATE_STOPPED}; - private static final int STATE_STOPPED = 0; - private static final int STATE_RUNNING_FWD = 1; - private static final int STATE_RUNNING_BKWD = 2; - private static final int STATE_ROTATE_TO = 3; - - // common registers - private static final int REG_ALL_MOTORCONTROL = 0x40; - private static final int REG_BATTERY = 0x54; - private static final int REG_ENCODERSREAD = 0x4C; // used by tachmonitor to read both encoders at once - // register map for the motor-specific registers - private static final int REG_IDX_ENCODER_TARGET = 0; - private static final int REG_IDX_MODE = 1; - private static final int REG_IDX_POWER = 2; - private static final int REG_IDX_ENCODER_CURRENT = 3; - static final int[][] REGISTER_MAP = // [REG_IDX_xxx][channel] - {{0x40, 0x48}, // Encoder Target (write) - {0x44, 0x47}, // Mode - {0x45, 0x46}, // Power - {0x4C, 0x50} // Encoder Value (read) - }; - - // Mode OR masks - private static final int MODEBIT_REVERSE = 0x08; -// private static final int MODEBIT_NTO = 0x10; -// private static final int MODEBIT_ERROR = 0x40; - private static final int MODEBIT_BUSY = 0x80; - private static final int MODEBIT_SEL_POWER = 0x00; - private static final int MODEBIT_SEL_SPEED = 0x01; - private static final int MODEBIT_SEL_POSITION = 0x02; - private static final int MODEBIT_SEL_RST_ENCODER = 0x03; - - // motor parameters - private int[][] motorParams = new int[4][CHANNELS]; - private static final int MOTPARAM_POWER = 0; // current power value - private static final int MOTPARAM_REGULATED = 1; // 0=false=power control, 1=speed control - private static final int MOTPARAM_REVERSED = 2; // 1=reversed, 0= normal - private static final int MOTPARAM_ROTATE = 3; // 1=rotate to target mode - static final int MOTPARAM_OP_TRUE=1; - static final int MOTPARAM_OP_FALSE=0; - - // motor and monitor instance buckets - Object[] motors= new Object[CHANNELS]; - BUSYMonitor[] bUSYMonitors = new BUSYMonitor[CHANNELS]; - TachoMonitor tachoMonitor; - boolean[] busyMonitorWaiting = {false,false}; - - private static final byte MOTTYPE_EMPTY = -1; - private static final byte MOTTYPE_BASIC = 0; - private static final byte MOTTYPE_ENCODER = 1; - private static final byte MOTTYPE_REGULATED = 2; - byte[] motorType = {MOTTYPE_EMPTY,MOTTYPE_EMPTY}; - - // I2C buffer - private byte[] buf = new byte[12]; - - private int[] limitangle = {0,0}; - - /** - * Instantiate a HiTechnic TETRIX Motor Controller connected to the given port and daisy chain position. - * - * @param port The sensor port the controller (if daisy-chained, the first) is connected to. - * @param daisyChainPosition The position of the controller in the daisy chain. - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_1 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_2 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_3 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_4 - * @throws IllegalStateException if a Motor Controller was not found with given port and daisyChainPosition - */ - public TetrixMotorController(I2CPort port, int daisyChainPosition) { - super(port, daisyChainPosition); - address = daisyChainPosition; - if (!(getVendorID().equalsIgnoreCase(TetrixControllerFactory.TETRIX_VENDOR_ID) && - getProductID().equalsIgnoreCase(TetrixControllerFactory.TETRIX_MOTORCON_PRODUCT_ID))) { - throw new IllegalStateException("Not a motor controller"); - } - initController(); - - // This thread will keep the controller active. Without I2C activity within 2.5 seconds, it times out. - // We could use the NTO bit of mode (MODEBIT_NTO) to keep the controller from timing - // out but the motors would still run if the EV3 faulted, was shutdown, etc. which could be unsafe with big, - // metal robots with sharp slicing attachments. - Thread t1 = new Thread(new Runnable(){ - public void run() { - byte[] buf1 = new byte[1]; - for (;;){ - getData(REG_VERSION, buf1, 0); - Delay.msDelay(KEEPALIVE_PING_INTERVAL); - // let the thread die if we are constantly getting tachocounts as this will keep the contoller active instead - if (tachoMonitorAlive()) break; - } - } - }); - t1.setDaemon(true); - t1.start(); - } - - // When a rotate is issued, an instance monitors the BUSY bit and sets STATE_STOPPED when the command completes. - // Also does any required RegulatedMotorListener STOP and notifies any wait() in waitRotateComplete(). - // Used by rotate() method only. - private class BUSYMonitor extends Thread { - int channel; - BUSYMonitor(int channel){ - this.channel = channel; - } - @Override - public void run(){ - byte buf1[] = {(byte)MODEBIT_BUSY}; - while ((buf1[0] & MODEBIT_BUSY) == MODEBIT_BUSY) { - Delay.msDelay(100); - //System.out.println("bsy"); - getData(REGISTER_MAP[REG_IDX_MODE][channel], buf1, 1); - } - motorState[channel]=STATE_STOPPED; - if (motorType[channel]==MOTTYPE_REGULATED) { - ((TetrixRegulatedMotor) motors[channel]).doListenerState(TetrixRegulatedMotor.LISTENERSTATE_STOP); - } - //System.out.println("busy done"); - // exit any wait for state of [ImmediateReturn = false] - synchronized (bUSYMonitors[channel]) { - busyMonitorWaiting[channel]=false; - bUSYMonitors[channel].notify(); - } - } - } - - // used by TetrixRegulatedMotor to monitor/manage tacho-related - private class TachoMonitor extends Thread{ - private static final int POLL_DELAY_MS = 100; - - private boolean threadDie = false; - private int[] TachoCount = new int[CHANNELS]; - private byte[] buffer = new byte[8]; - private volatile float[] degpersec = new float[CHANNELS]; - private float[][] samples = new float[CHANNELS][3]; - private int sampleIndex=0; - private boolean[] ismoving = new boolean[CHANNELS]; - - TachoMonitor(){ - this.setDaemon(true); - } - - synchronized int getTachoCount(int channel) { - return TachoCount[channel]; - } - - synchronized int getSpeed(int channel) { - return (int)(degpersec[channel] * 100); - } - - boolean isMoving(int channel){ - return ismoving[channel]; - } - - @Override - public void run(){ - int retVal; - int failCount; - int[] tachoBegin = new int[CHANNELS]; - long endTime, beginTime, timeDelta; - float[] degpersecAccum = new float[CHANNELS]; - - beginTime = System.currentTimeMillis(); - Main: while (!threadDie){ - Delay.msDelay(POLL_DELAY_MS); - getData(REG_ENCODERSREAD, buffer, 8); - - // baseline the time after successful I2C transaction - endTime = System.currentTimeMillis(); - timeDelta = endTime - beginTime; - beginTime = endTime; - - // parse the buffer into the counts - synchronized (this){ - TachoCount[MOTOR_1] = EndianTools.decodeIntBE(buffer, 0); - TachoCount[MOTOR_2] = EndianTools.decodeIntBE(buffer, 4); - } - - // Do velocity calcs (deg per sec) - for (int i=0;i= samples[i].length) sampleIndex = 0; - } - // save a dps sample - samples[i][sampleIndex] = (float)Math.abs(TachoCount[i] - tachoBegin[i]) / timeDelta * 250; - tachoBegin[i] = TachoCount[i]; - } - - // average the samples and the last result (degpersec) - for (int ii=0;iiTetrixMotor instance that is associated with the motorID. - * - * @param motorID The motor ID number. This is indicated on the HiTechnic Motor Controller and is - * represented using {@link #MOTOR_1} or {@link #MOTOR_2}. - * @return The TetrixMotor instance - * @throws IllegalArgumentException if invalid motorID - * @throws UnsupportedOperationException if motorID has already been used for a Tetrix motor instance - * other than TetrixMotor. - * @see lejos.hardware.device.tetrix.TetrixMotor - * @see #getEncoderMotor - * @see #getRegulatedMotor - */ - public TetrixMotor getBasicMotor(int motorID) { - getMotor(motorID, MOTTYPE_BASIC); - return (TetrixMotor) motors[motorID]; - } - - /** - * Get a TetrixEncoderMotor instance that is associated with the motorID. The motor must - * have an encoder installed for a TetrixEncoderMotor instance to work correctly. - * - * @param motorID The motor ID number. This is indicated on the HiTechnic Motor Controller and is - * represented using {@link #MOTOR_1} or {@link #MOTOR_2}. - * @return The TetrixEncoderMotor instance - * @throws IllegalArgumentException if invalid motorID - * @throws UnsupportedOperationException if motorID has already been used for a Tetrix motor instance - * other than TetrixEncoderMotor. - * @see lejos.hardware.device.tetrix.TetrixEncoderMotor - * @see #getBasicMotor - * @see #getRegulatedMotor - */ - public TetrixEncoderMotor getEncoderMotor(int motorID) { - getMotor(motorID, MOTTYPE_ENCODER); - return (TetrixEncoderMotor) motors[motorID]; - } - - /** - * Get a TetrixRegulatedMotor instance that is associated with the motorID. The motor must - * have an encoder installed for a TetrixRegulatedMotor instance to work correctly. - * - * @param motorID The motor ID number. This is indicated on the HiTechnic Motor Controller and is - * represented using {@link #MOTOR_1} or {@link #MOTOR_2}. - * @return The TetrixRegulatedMotor instance - * @throws IllegalArgumentException if invalid motorID - * @throws UnsupportedOperationException if motorID has already been used for a Tetrix motor instance - * other than TetrixRegulatedMotor. - * @see TetrixRegulatedMotor - * @see #getBasicMotor - * @see #getEncoderMotor - */ - public TetrixRegulatedMotor getRegulatedMotor(int motorID) { - getMotor(motorID, MOTTYPE_REGULATED); - return (TetrixRegulatedMotor) motors[motorID]; - } - - private void getMotor(int motorID, byte motorTypeValue){ - if (motorIDMOTOR_2) { - throw new IllegalArgumentException("Invalid motor ID"); - } - - if (motorType[motorID]==MOTTYPE_EMPTY) { - switch(motorTypeValue) { - case MOTTYPE_REGULATED: - motors[motorID]=new TetrixRegulatedMotor(this, motorID); - break; - case MOTTYPE_ENCODER: - motors[motorID]=new TetrixEncoderMotor(this, motorID); - break; - case MOTTYPE_BASIC: - motors[motorID]=new TetrixMotor(this, motorID); - } - motorType[motorID]=motorTypeValue; - } - if (motorType[motorID]!=motorTypeValue) { - throw new UnsupportedOperationException("Wrong motor type"); - } - - //start the tacho monitor if not already for encoder-enabled motors - if (motorTypeValue > MOTTYPE_BASIC && tachoMonitor==null) { - this.tachoMonitor = new TachoMonitor(); - this.tachoMonitor.start(); - } - } - -// void dumpArray(int[] arr) { -// for (int i=0;iRegulatedMotor. The Tetrix motor must have an - * encoder installed and connected to - * the controller for the methods in this class to work. If an encoder is not installed, use the {@link TetrixMotor} - * class instead. - *

Use {@link TetrixMotorController#getRegulatedMotor} to retrieve a TetrixRegulatedMotor instance. - * - * @author Kirk P. Thompson - */ -public class TetrixRegulatedMotor extends TetrixEncoderMotor implements RegulatedMotor{ - static final int LISTENERSTATE_STOP = 0; - static final int LISTENERSTATE_START = 1; - - RegulatedMotorListener listener; - - TetrixRegulatedMotor(TetrixMotorController mc, int channel) { - super(mc, channel); - super.setRegulate(true); - } - - /** - * OVERRIDDEN TO NOT ALLOW CHANGE OF REGULATED STATE as the TetrixRegulatedMotor class must use regulation. - * Motors are always in - * regulated mode when using the TetrixRegulatedMotor class. - * - * @param regulate Ignored - */ - @Override - public void setRegulate(boolean regulate){ - // ignore and don't allow change of regulation - } - - @SuppressWarnings("hiding") - public void addListener(RegulatedMotorListener listener) { - this.listener = listener; - } - - void doListenerState(int listenerState) { - if (this.listener == null) return; - if (listenerState == LISTENERSTATE_STOP) { - // wait for a complete stop before notifying - new Thread(new Runnable(){ - public void run() { - waitComplete(); - listener.rotationStopped(TetrixRegulatedMotor.this, getTachoCount(), false, System.currentTimeMillis()); - }}).start(); - } else { - this.listener.rotationStarted(this, getTachoCount(), false, System.currentTimeMillis()); - } - } - - public RegulatedMotorListener removeListener() { - RegulatedMotorListener old = this.listener; - this.listener = null; - return old; - } - - /** - * Return the current rotational speed calculated from the encoder position every 100 ms. This will - * likely differ from what was specified in setSpeed. - * - * @return The current rotational speed in deg/sec - */ - public int getRotationSpeed() { - return Math.round(.01f * mc.doCommand(TetrixMotorController.CMD_GETSPEED, 0, channel)); - } - - public void stop(boolean immediateReturn) { - super.stop(); - if (!immediateReturn) waitComplete(); - } - - public void flt(boolean immediateReturn) { - super.flt(); - if (!immediateReturn) waitComplete(); - } - - public void waitComplete() { - super.waitRotateComplete(); - } - - /** - * Rotate by the requested number of degrees while blocking until completion. - * - * @param angle number of degrees to rotate relative to the current position. - */ - public void rotate(int angle) { - rotate(angle, false); - } - - /** - * Rotate to the target angle while blocking until completion. - * - * @param limitAngle Angle [in degrees] to rotate to. - */ - public void rotateTo(int limitAngle) { - rotateTo(limitAngle, false); - } - - /** - * Sets desired motor speed, in degrees per second. Since the TETRIX Motor Controller only has power adjustment, - * the power value is derived from the passed speed value as: - *
- *

  power = Math.round((speed - 0.5553f) * 0.102247398f);
- * and as such, the actual speed value will not be exact. - *

- * The maximum reliably sustainable velocity for the TETRIX DC Gear motor P/N 739023 (which was used as the - * test case for creating this class) is 154 RPM => 924 degs/sec. - * - * @param speed value in degrees/sec - * @see #getSpeed - */ - public void setSpeed(int speed) { - // experimental data gives: speed = 9.7802 * power + 0.5553 - int power = Math.round((Math.abs(speed) - 0.5553f) * 0.102247398f); - super.setPower(power); - - } - - /** - * Return the speed value calculated from the actual power value as: - *
- *

  speed = Math.round(9.7802f * super.getPower() + 0.5553f);
- * and as such, the actual speed value may not be what was set with setSpeed. - * - * @return The speed value (converted from power value) in degrees/sec - * @see #setSpeed - */ - public int getSpeed() { - int speed = Math.round(9.7802f * super.getPower() + 0.5553f); - return speed; - } - - /** - * NOT IMPLEMENTED as the TEXTRIX motor controller does not support this command. - * @return Always 924 degrees/sec - */ - public float getMaxSpeed() { - return 924f; - } - - /** - * NOT IMPLEMENTED as the TEXTRIX motor controller does not support this command. - * @return Always false - */ - public boolean isStalled() { - return false; - } - - /** - * NOT IMPLEMENTED as the TEXTRIX motor controller does not support this command. - */ - public void setStallThreshold(int error, int time) { - // do nothing - } - - /** - * NOT IMPLEMENTED as the TEXTRIX motor controller does not support this command. - * @param acceleration Ignored - */ - public void setAcceleration(int acceleration) { - // do nothing - } - - @Override - public void close() { - // Do nothing - } - - @Override - public void synchronizeWith(RegulatedMotor[] syncList) - { - // TODO Auto-generated method stub - - } - - @Override - public void startSynchronization() - { - // TODO Auto-generated method stub - - } - - @Override - public void endSynchronization() - { - // TODO Auto-generated method stub - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServo.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServo.java deleted file mode 100644 index b12af14..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServo.java +++ /dev/null @@ -1,95 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.robotics.Servo; - -/** - * Basic servo motor abstraction. Servos are driven by a PWM signal from the controller with varying pulse widths - * controlling the rotational position of the servo actuator shaft. - *

- * The HiTechnic Servo Controller allows setting of the PWM output from 0.75 - 2.25ms. Note that some servos may hit their - * internal mechanical limits at each end of this range causing them to consume excessive current and potentially be damaged. - * - * @author Kirk P. Thompson - */ -public class TetrixServo implements Servo{ - private TetrixServoController sc; - private int channel; - - TetrixServo(TetrixServoController sc, int channel) { - this.sc=sc; - this.channel=channel; - } - - /** - * Set the allowable pulse width operating range of this servo in microseconds and the total travel range. - * Default for pulse width at instantiation is 750 & 2250 microseconds. Default for travel is 200 degrees. - *

- * The midpoint - * of the pulse width operating range should normally be 1500 microseconds so the range extents should reflect this. - *

- * This information must reflect the appropriate specifications and/or empirical characterization data of the specific - * servo used for the setAngle() method to be able to position the servo accurately. - * - * @param microsecLOW The low end of the servos response/operating range in microseconds - * @param microsecHIGH The high end of the servos response/operating range in microseconds - * @param travelRange The total mechanical travel range of the servo in degrees - * @throws IllegalArgumentException if the range isn't within 750 and 2250 - * @see #setAngle - */ - public void setRange (int microsecLOW, int microsecHIGH, int travelRange) throws IllegalArgumentException { - sc.setPulseRange(channel, microsecLOW, microsecHIGH, travelRange); - } - - /** - * Sets the angle target of the servo. The positional accuracy of this method requires that setRange() - * be called with the - * correct parameters to establish proper ranging conversion to internal controller representation of servo position. - * - * @param angle Set servo angle in degrees. - * @see #setRange - * @see #getAngle - */ - public void setAngle(float angle){ - sc.setAngle(channel, angle); - } - - /** - * Returns the current servo angle as reverse calculated by the last call to setAngle(). This is calculated from the - * internal byte representation used (calculated by setAngle()) to control the servo so the resolution will be - * affected by ranging factors set with setRange() - *

- * The actual physical servo position may or may not be at the reported angle if mechanical limits have been reached. - * - * @return Current servo angle - * @see #setRange - * @see #setAngle - */ - public float getAngle(){ - return sc.getAngle(channel); - } - - /** - * Set the PWM pulse width for the servo. This must be in the range defined for the servo. This method allows manipulation - * of the servo position based on absolute pulse widths in microseconds. - *

- * A servo pulse of 1500 microseconds (1.5 ms) width will typically set the servo to its "neutral" position. This is the - * "standard pulse servo mode" used by all hobby analog servos. - *

- * The HiTechic Servo Controller allows setting of the PWM output from 750 to 2250 microseconds with a step resolution - * of 5.88 microseconds (1 byte is used to control the pulse width output) and this method will calculate and use the stepped - * value closest to value passed in microSeconds. - *

Note that some servos may hit their internal mechanical limits at each end of this range causing them to consume excessive current - * and potentially be damaged. - * - * @param microSeconds The pulse width time in microseconds - * @throws IllegalArgumentException if the range isn't within 750 and 2250 - * @see #setRange - */ - public void setpulseWidth(int microSeconds) throws IllegalArgumentException { - sc.setPulseWidth(channel, microSeconds); - } - - public int getpulseWidth(){ - return sc.getPulseWidth(channel); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServoController.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServoController.java deleted file mode 100644 index 33519ab..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/TetrixServoController.java +++ /dev/null @@ -1,303 +0,0 @@ -package lejos.hardware.device.tetrix; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.sensor.I2CSensor; -import lejos.utility.Delay; - -// This class was developed using the HiTec HS-475HB medium duty servo as the use/test case: -// Control System: +Pulse Width Control 1500usec Neutral -// Required Pulse: 3-5 Volt Peak to Peak Square Wave -// Operating Voltage: 4.8-6.0 Volts -// Operating Temperature Range: -20 to +60 Degree C -// Operating Speed (4.8V): 0.22sec/60 deg at no load -// Operating Speed (6.0V): 0.18sec/60 deg at no load -// Stall Torque (4.8V): 66.6 oz/in. (4.8kg.cm) -// Stall Torque (6.0V): 83.3 oz/in. (6.0kg.cm) -// Operating Angle: 45 Deg. one side pulse traveling 400usec -// 360 Modifiable: Yes -// Direction: Clockwise/Pulse Traveling 1500 to 1900usec -// Current Drain (4.8V): 8mA/idle and 150mA no load operating -// Current Drain (6.0V): 8.8mA/idle and 180mA no load operating -// Dead Band Width: 8usec -// Motor Type: 3 Pole Ferrite Motor -// Potentiometer Drive: Indirect Drive -// Bearing Type: Top Ball Bearing, Lower Bushing -// Gear Type: Karbonite Gears -// Connector Wire Length: 11.81" (300mm) -// Dimensions: See Schematic -// Weight: 1.59oz (45g) - -/** - * HiTechnic Servo Controller abstraction. Provides TetrixServo instances which are used to control - * the Tetrix servos. - *

- * Servos are driven by a PWM signal with varying pulse widths - * controlling the rotational position of the servo actuator. - * The pulse nominally ranges from 1.0 ms to 2.0 ms with 1.5 ms always being center of range. - * Pulse widths outside this range can be used for "overtravel" -moving the servo beyond its normal range. - *

- * As an example, for a servo with - * a 90 deg. travel range, a pulse width of 1.5 ms (1500 microseconds) will typically set the servo to its "neutral" position or 45 degrees, - * a pulse of 1.25 ms could set it to 0 degrees and a pulse of 1.75 ms to 90 degrees. - * The physical limits and timings of the servo hardware varies between brands and models, but a - * general 90 degree servo's angular motion will travel somewhere in the range of 90 deg. - 120 deg. and the - * neutral position is almost always at 1.5 ms. This is the "standard pulse servo mode" used by all hobby analog servos. - *

- * The HiTechic Servo Controller allows setting of the PWM output from 0.75 - 2.25ms. Note that some servos may hit their - * internal mechanical limits at each end of this range causing them to consume excessive current and potentially be damaged. - *

- * Use {@link TetrixControllerFactory#newServoController} to retrieve a TetrixServoController instance. - * - * @see lejos.hardware.device.tetrix.TetrixControllerFactory - * @author Kirk P. Thompson - */ -public class TetrixServoController extends I2CSensor { - /** - * Represents the servo connected to Channel 1 as indicated on the controller - */ - public static final int SERVO_1 = 0; - - /** - * Represents the servo connected to Channel 2 as indicated on the controller - */ - public static final int SERVO_2 = 1; - - /** - * Represents the servo connected to Channel 3 as indicated on the controller - */ - public static final int SERVO_3 = 2; - - /** - * Represents the servo connected to Channel 4 as indicated on the controller - */ - public static final int SERVO_4 = 3; - - /** - * Represents the servo connected to Channel 5 as indicated on the controller - */ - public static final int SERVO_5 = 4; - - /** - * Represents the servo connected to Channel 6 as indicated on the controller - */ - public static final int SERVO_6 = 5; - - private static final int CHANNELS = 6; - private static final int KEEPALIVE_PING_INTERVAL = 9900; - private static final int REG_PWM_ENABLE = 0x48; - private static final int REG_SERVO_1_POS = 0x42; - private static final int REG_STEP_TIME = 0x41; - private static final int REG_STATUS = 0x40; - - // PWM Mode values - private static final byte PWMMODE_ENABLE = 0x00; - private static final byte PWMMODE_DISABLE = (byte)0xFF; -// private static final byte PWMMODE_ENABLE_NTO = (byte)0xAA; - - // controller characteristics - private static final int CONTROLLER_PULSE_RANGE_LOW = 750; - private static final int CONTROLLER_PULSE_RANGE_HIGH = 2250; - private static final int DEFAULT_HITEC_MOTION_RANGE = 200; - private static final float PULSE_RESOLUTION = 255f/(CONTROLLER_PULSE_RANGE_HIGH-CONTROLLER_PULSE_RANGE_LOW) ; - - // servo parameters - private int[][] servoParams = new int[4][CHANNELS]; - private static final int SRVOPARAM_PULSEWIDTH_RANGE_LOW = 0; // low pulse width range in usec - private static final int SRVOPARAM_PULSEWIDTH_RANGE_HIGH = 1; // high pulse width range in usec - private static final int SRVOPARAM_ROTATION_RANGE = 2; // Range of servo in degrees - private static final int SRVOPARAM_PULSEBYTE = 3; // current pulse width in usec - - // servo instances - private TetrixServo[] servos= new TetrixServo[CHANNELS]; - - /** - * Instantiate for a HiTechnic TETRIX Servo Controller connected to the given port and daisy chain position. - * - * @param port The sensor port the controller (if daisy-chained, the first) is connected to. - * @param daisyChainPosition The position of the controller in the daisy chain. - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_1 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_2 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_3 - * @see TetrixControllerFactory#DAISY_CHAIN_POSITION_4 - * @throws IllegalStateException if a Servo Controller was not found with given port and daisyChainPosition - */ - public TetrixServoController(I2CPort port, int daisyChainPosition) { - super(port, daisyChainPosition); - address = daisyChainPosition; - if (!(getVendorID().equalsIgnoreCase(TetrixControllerFactory.TETRIX_VENDOR_ID) && - getProductID().equalsIgnoreCase(TetrixControllerFactory.TETRIX_SERVOCON_PRODUCT_ID))) { - throw new IllegalStateException("Not a servo controller"); - } - initController(); - // This thread will keep the controller active. Without I2C activity within 10 seconds, it times out. - // We could use the PWM Enable value 0xAA in REG_PWM_ENABLE to keep the controller from timing - // out but the servos would still be powered if the EV3 faulted, was shutdown, etc. - Thread t1 = new Thread(new Runnable(){ - public void run() { - byte[] buf = new byte[1]; - for (;;){ - getData(REG_VERSION, buf, 0); - Delay.msDelay(KEEPALIVE_PING_INTERVAL); - } - } - }); - t1.setDaemon(true); - t1.start(); - } - - /** - * Get the TetrixServo instance that is associated with the passed servoID. - * - * @param servoID The motor ID number SERVO_1 to SERVO_6. This is indicated on the - * HiTechnic Servo Controller. - * @return The TetrixServo instance associated with the labeled channel - * @see #SERVO_1 - * @see #SERVO_2 - * @see #SERVO_3 - * @see #SERVO_4 - * @see #SERVO_5 - * @see #SERVO_6 - */ - public TetrixServo getServo(int servoID) { - if (servoIDSERVO_6) { - throw new IllegalArgumentException("Invalid servo ID"); - } - if (servos[servoID]==null) servos[servoID]=new TetrixServo(this, servoID); - return servos[servoID]; - } - - private void setPulse(int channel, byte pulseByte) { - // set the pulse width - servoParams[SRVOPARAM_PULSEBYTE][channel] = pulseByte & 0xff; - sendData(REG_SERVO_1_POS + channel, pulseByte); - sendData(REG_PWM_ENABLE, PWMMODE_ENABLE); - } - - /** - * Set the operating range of the servo in microseconds. Default at instantiation is 750 & 2250. - * @param microsecLOW the low end of the servos response range in microseconds - * @param microsecHIGH the high end of the servos response range in microseconds - * @throws IllegalArgumentException if the range isn't within 750 and 2250 - */ - synchronized void setPulseRange (int channel, int microsecLOW, int microsecHIGH, int travelRange) throws IllegalArgumentException { - if (microsecLOW < CONTROLLER_PULSE_RANGE_LOW || - microsecHIGH > CONTROLLER_PULSE_RANGE_HIGH || - microsecLOW >= microsecHIGH) { - throw new IllegalArgumentException("Invalid range"); - } - servoParams[SRVOPARAM_PULSEWIDTH_RANGE_LOW][channel] = microsecLOW; - servoParams[SRVOPARAM_PULSEWIDTH_RANGE_HIGH][channel] = microsecHIGH; - servoParams[SRVOPARAM_ROTATION_RANGE][channel] = travelRange; - } - - synchronized void setPulseWidth (int channel, int pulseWidth) throws IllegalArgumentException { - if (pulseWidth < CONTROLLER_PULSE_RANGE_LOW || pulseWidth > CONTROLLER_PULSE_RANGE_HIGH) { - throw new IllegalArgumentException("Invalid pulse value"); - } - byte workingByte; - // calc byte value for pulse width - workingByte = (byte)(Math.round((pulseWidth-CONTROLLER_PULSE_RANGE_LOW)*PULSE_RESOLUTION)&0xff); - setPulse(channel, workingByte); - } - - synchronized int getPulseWidth (int channel) { - return (int)((float)servoParams[SRVOPARAM_PULSEBYTE][channel] / PULSE_RESOLUTION + CONTROLLER_PULSE_RANGE_LOW); - } - - synchronized float getAngle(int channel) { - float servoResolution = (servoParams[SRVOPARAM_PULSEWIDTH_RANGE_HIGH][channel] - - (float)servoParams[SRVOPARAM_PULSEWIDTH_RANGE_LOW][channel]) / servoParams[SRVOPARAM_ROTATION_RANGE][channel]; - float angle = (servoParams[SRVOPARAM_PULSEBYTE][channel] - (float)servoParams[SRVOPARAM_PULSEWIDTH_RANGE_LOW][channel] - * PULSE_RESOLUTION - + (float)CONTROLLER_PULSE_RANGE_LOW * PULSE_RESOLUTION) / (servoResolution * PULSE_RESOLUTION); - return angle; - } - - synchronized void setAngle(int channel, float angle){ - if (angle < 0 || angle > servoParams[SRVOPARAM_ROTATION_RANGE][channel]) { - throw new IllegalArgumentException("Invalid range value"); - } - // ** calc the byte value of angle using the defined ranges of the servo. - // get the pulse resolution of the specific servo - // multiply by requested angle - // add offset between servo low range and contoller low range to determine actual target pulse width - // multiply by controller range pulse resolution [inverse] constant to get byte - float servoResolution = (servoParams[SRVOPARAM_PULSEWIDTH_RANGE_HIGH][channel] - - (float)servoParams[SRVOPARAM_PULSEWIDTH_RANGE_LOW][channel]) / servoParams[SRVOPARAM_ROTATION_RANGE][channel]; - int theByte = (int)( - ( servoResolution * angle - + (servoParams[SRVOPARAM_PULSEWIDTH_RANGE_LOW][channel] - CONTROLLER_PULSE_RANGE_LOW) - ) - * PULSE_RESOLUTION); - setPulse(channel, (byte)(theByte & 0xff)); - } - - private void initController() { - for (int i = 0;ifalse when the step time is set to 0 (disabled). - * - * @return true if any servo is moving to position. - * @see #setStepTime - */ - public synchronized boolean isMoving(){ - byte[] buf = new byte[1]; - this.getData(REG_STATUS, buf, 1); - return buf[0]!=0; - } - - /** - * Set all servos connected to this controller to float mode. This means they are powered down and will not attempt - * to hold their current - * position. The next call to any motion command for any servo will re-enable power to all servo channels. - */ - public synchronized void flt() { - sendData(REG_PWM_ENABLE, PWMMODE_DISABLE); - } - - /** - * Sets the step time used for all servos on this controller. This sets the step time for the servo channel - * which has the furthest to move. Other servo channels which are not at their designated positions yet will run at a - * slower rate to ensure they reach their destination positions at the same time. The controller defaults to 0 on power-up. - *

- * The step time can be considered a delay before progressing to the next step. For example, if a servo is positioned - * at 1500 microseconds pulse width, and you give it a - * new position command of 2000 microseconds, it will normally go as fast as it can to get to the new position. If you want it to - * go to the new position but not at the maximum output, you can set the step to a value from 0 to 15. - *

- * One of the main things it could be useful for, is if you have two servos with different loads, and you want them - * to be as much in sync as possible. You can set the speed to slow the controller from changing the servo signals instantly. - *

- * The isMoving() method always returns false if the step time is set to zero. - * - * @param step Step Time, 0-15. Setting to 0 disables step time. - * @throws IllegalArgumentException If step is not in the range 0 to 15 - * @see #getStepTime - * @see #isMoving - */ - // TODO this needs to be tested when I get more than one servo - public synchronized void setStepTime(int step){ - if (step < 0 || step > 15) throw new IllegalArgumentException("Invalid value"); - sendData(REG_STEP_TIME, (byte)step); - } - - /** - * Gets the step time used for all servos on this controller. - * @return The step time 0-15. 0 means step is disabled. - * @see #setStepTime - */ - public synchronized int getStepTime(){ - byte[] buf = new byte[1]; - this.getData(REG_STEP_TIME, buf, 1); - return buf[0] & 0xff; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/device/tetrix/package-info.java b/ev3classes/src/main/java/lejos/hardware/device/tetrix/package-info.java deleted file mode 100644 index b626466..0000000 --- a/ev3classes/src/main/java/lejos/hardware/device/tetrix/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/** - *

- * HiTechnic Tetrix Motor and Servo controller support. - *

- * For unit details, see: - *
- * http://www.legoeducation.us/eng/product/hitechnic_dc_motor_controller/1648 - * - *
- * - * http://www.legoeducation.us/eng/product/hitechnic_servo_controller/1649 - * - *

- */ -package lejos.hardware.device.tetrix; diff --git a/ev3classes/src/main/java/lejos/hardware/ev3/EV3.java b/ev3classes/src/main/java/lejos/hardware/ev3/EV3.java deleted file mode 100644 index aaf3345..0000000 --- a/ev3classes/src/main/java/lejos/hardware/ev3/EV3.java +++ /dev/null @@ -1,8 +0,0 @@ -package lejos.hardware.ev3; - -import lejos.hardware.Brick; - -public interface EV3 extends Brick -{ -} - diff --git a/ev3classes/src/main/java/lejos/hardware/ev3/LocalEV3.java b/ev3classes/src/main/java/lejos/hardware/ev3/LocalEV3.java deleted file mode 100644 index a027194..0000000 --- a/ev3classes/src/main/java/lejos/hardware/ev3/LocalEV3.java +++ /dev/null @@ -1,227 +0,0 @@ -package lejos.hardware.ev3; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; - -import lejos.hardware.Audio; -import lejos.hardware.BrickFinder; -import lejos.hardware.Key; -import lejos.hardware.Keys; -import lejos.hardware.LED; -import lejos.hardware.Power; -import lejos.hardware.Bluetooth; -import lejos.hardware.LocalBTDevice; -import lejos.hardware.LocalWifiDevice; -import lejos.hardware.Wifi; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.TextLCD; -import lejos.hardware.port.Port; -import lejos.hardware.video.Video; -import lejos.internal.ev3.EV3Audio; -import lejos.internal.ev3.EV3GraphicsLCD; -import lejos.internal.ev3.EV3Key; -import lejos.internal.ev3.EV3Keys; -import lejos.internal.ev3.EV3LCDManager; -import lejos.internal.ev3.EV3LED; -import lejos.internal.ev3.EV3Port; -import lejos.internal.ev3.EV3Battery; -import lejos.internal.ev3.EV3TextLCD; -import lejos.internal.ev3.EV3Video; - -/** - * This class represents the local instance of an EV3 device. It can be used to - * obtain access to the various system resources (Sensors, Motors etc.). - * @author andy - * - */ -public class LocalEV3 implements EV3 -{ - public static final int ID_UP = 0x1; - public static final int ID_ENTER = 0x2; - public static final int ID_DOWN = 0x4; - public static final int ID_RIGHT = 0x8; - public static final int ID_LEFT = 0x10; - public static final int ID_ESCAPE = 0x20; - - public static final LocalEV3 ev3 = new LocalEV3(); - protected EV3LCDManager lcdManager; - protected final Power battery = new EV3Battery(); - protected final Audio audio = EV3Audio.getAudio(); - protected ArrayList ports = new ArrayList(); - protected TextLCD textLCD; - protected GraphicsLCD graphicsLCD; - protected EV3Keys keys = new EV3Keys(); - protected final LED led = new EV3LED(); - protected Video video; - - protected final Key enter = new EV3Key(keys, "Enter"); - protected final Key escape = new EV3Key(keys, "Escape"); - protected final Key left = new EV3Key(keys, "Left"); - protected final Key right = new EV3Key(keys, "Right"); - protected final Key up = new EV3Key(keys, "Up"); - protected final Key down = new EV3Key(keys, "Down"); - - protected final Key[] keyArray = { up, enter, down, right, left, escape }; - - private LocalEV3() - { - // Create the port objects - ports.add(new EV3Port("S1", EV3Port.SENSOR_PORT, 0)); - ports.add(new EV3Port("S2", EV3Port.SENSOR_PORT, 1)); - ports.add(new EV3Port("S3", EV3Port.SENSOR_PORT, 2)); - ports.add(new EV3Port("S4", EV3Port.SENSOR_PORT, 3)); - ports.add(new EV3Port("A", EV3Port.MOTOR_PORT, 0)); - ports.add(new EV3Port("B", EV3Port.MOTOR_PORT, 1)); - ports.add(new EV3Port("C", EV3Port.MOTOR_PORT, 2)); - ports.add(new EV3Port("D", EV3Port.MOTOR_PORT, 3)); - } - - public static EV3 get() - { - return ev3; - } - - /** {@inheritDoc} - */ - @Override - public Port getPort(String portName) - { - for(EV3Port p : ports) - if (p.getName().equals(portName)) - return p; - throw new IllegalArgumentException("No such port " + portName); - } - - /** {@inheritDoc} - */ - @Override - public Power getPower() - { - return battery; - } - - protected void initLCD() - { - if (lcdManager == null) - { - lcdManager = EV3LCDManager.getLocalLCDManager(); - lcdManager.newLayer("LCD"); - } - } - - @Override - public TextLCD getTextLCD() - { - initLCD(); - if (textLCD == null) - { - initLCD(); - textLCD = new EV3TextLCD("LCD"); - } - return textLCD; - } - - @Override - public GraphicsLCD getGraphicsLCD() - { - initLCD(); - if (graphicsLCD == null) - { - initLCD(); - graphicsLCD = new EV3GraphicsLCD("LCD"); - } - return graphicsLCD; - } - - @Override - public TextLCD getTextLCD(Font f) - { - initLCD(); - return new EV3TextLCD("LCD", f); - } - - /** {@inheritDoc} - */ - @Override - public Audio getAudio() - { - return audio; - } - - /** {@inheritDoc} - */ - @Override - public Video getVideo() - { - if (video == null) - video = new EV3Video(); - return video; - } - - - @Override - public boolean isLocal() - { - return true; - } - - @Override - public String getType() - { - return "EV3"; - } - - @Override - public String getName() - { - try - { - BufferedReader in = new BufferedReader(new FileReader("/etc/hostname")); - String name = in.readLine().trim(); - in.close(); - return name; - } catch (IOException e) - { - return "Not known"; - } - } - - @Override - public LocalBTDevice getBluetoothDevice() - { - return Bluetooth.getLocalDevice(); - } - - @Override - public LocalWifiDevice getWifiDevice() - { - return Wifi.getLocalDevice("wlan0"); - } - - @Override - public void setDefault() - { - BrickFinder.setDefault(this); - } - - @Override - public Key getKey(String name) - { - return keyArray[EV3Key.getKeyPos(name)]; - } - - @Override - public LED getLED() - { - return led; - } - - @Override - public Keys getKeys() - { - return keys; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/ev3/package-info.java b/ev3classes/src/main/java/lejos/hardware/ev3/package-info.java deleted file mode 100644 index a4a55bd..0000000 --- a/ev3classes/src/main/java/lejos/hardware/ev3/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * EV3 hardware access - */ -package lejos.hardware.ev3; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/gps/Coordinates.java b/ev3classes/src/main/java/lejos/hardware/gps/Coordinates.java deleted file mode 100644 index ea07d9a..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/Coordinates.java +++ /dev/null @@ -1,571 +0,0 @@ -package lejos.hardware.gps; - -import java.util.Enumeration; -import java.util.Vector; - -/** - * This class has been designed to manage coordinates - * using JSR-179 Location API - * http://www.jcp.org/en/jsr/detail?id=179 - * - * @author Juan Antonio Brenha Moral (calculateDistanceAndAzimuth by Charles Manning) - */ -public class Coordinates{ - private double latitude; - private double longitude; - private double altitude; - - /** - * Identifier for string coordinate representation Degrees, Minutes, decimal fractions of a minute - * See Also:Constant Field Values - */ - public static final int DD_MM=2; - - /** - * Identifier for string coordinate representation Degrees, Minutes, Seconds and decimal fractions of a second - * See Also:Constant Field Values - */ - public static final int DD_MM_SS=1; - - static final double EARTH_RADIUS = 6378137D; - - static float calculatedDistance = Float.NaN; - static float calculatedAzimuth = Float.NaN; - - /* Constructor */ - - /** - * Create a Coordinate object with 3 parameters: - * latitude, longitude and altitude - * - * @param latitude - * @param longitude - * @param altitude - */ - public Coordinates(double latitude, double longitude,double altitude) { - setLatitude(latitude); - setLongitude(longitude); - setAltitude(altitude); - } - - public Coordinates(double latitude, double longitude) { - this(latitude,longitude,0); - } - - /** - *

Returns the latitude component of this coordinate. Positive values indicate northern - * latitude and negative values southern latitude.

- * - *

The latitude is given in WGS84 datum.

- * @return the latitude in degrees - * @see #setLatitude(double) - * - */ - public double getLatitude() { - return latitude; - } - - /* - * Set Latitude - */ - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - /* - * Set Longitude - */ - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - /** - *

Returns the longitude component of this coordinate. Positive values indicate eastern longitude - * and negative values western longitude.

- *

The longitude is given in WGS84 datum.

- * - * @return the longitude in degrees - * @see #setLongitude(double) - */ - public double getLongitude() { - return longitude; - } - - /* - * Set Altitude in meters - */ - public void setAltitude(double altitude) { - this.altitude = altitude; - } - - /** - * Altitude above mean sea level. - * - * @return the altitude - */ - public double getAltitude() { - return altitude; - } - - /** - *

Calculates the azimuth between the two points according to - * the ellipsoid model of WGS84. The azimuth is relative to true north.

- * - *

The Coordinates object on which this method is called is considered - * the origin for the calculation and the Coordinates object passed - * as a parameter is the destination which the azimuth is calculated to.

- * - *

The azimuth (in degrees) increases clockwise. On this coordinate system, north is 0 degrees, - * east is 90 degrees, south is 180 degrees, and west is 270 degrees.

- * - *

When the origin is the North pole and the destination - * is not the North pole, this method returns 180.0. - * When the origin is the South pole and the destination is not - * the South pole, this method returns 0.0. If the origin is equal - * to the destination, this method returns 0.0.

- *

The implementation shall calculate the result as exactly as it can. - * However, it is required that the result is within 1 degree of the correct result.

- * - */ - public double azimuthTo(Coordinates to){ - if(to == null){ - throw new NullPointerException(); - }else{ - // TODO: Is there some way to make it not recalculate if it already calculated for these coordinates? Keep in mind coordinates can change. - // Perhaps it keeps a reference to last to coordinate. If values are the same, then doesn't recalculate. - calculateDistanceAndAzimuth(getLatitude(), getLongitude(), to.getLatitude(), to.getLongitude()); - while (calculatedAzimuth < 0) calculatedAzimuth += 360; - while(calculatedAzimuth >= 360) calculatedAzimuth -= 360; - return calculatedAzimuth; - } - } - -/*********************************** -UNTESTED as of April 7, 2009 - BB - ********************************* / - - /** - * Converts a double representation of a coordinate with decimal degrees into a string - * representation. There are string syntaxes supported are the same as for the - * #convert(String) method. The implementation shall provide as many significant - * digits for the decimal fractions as are allowed by the string syntax definition. - * - * @param coordinate - * a double representation of a coordinate - * @param outputType - * identifier of the type of the string representation wanted for output - * The constant {@link #DD_MM_SS} identifies the syntax 1 and the constant - * {@link #DD_MM} identifies the syntax 2. - * @throws IllegalArgumentException - * if the outputType is not one of the two constant values defined in this - * class or if the coordinate value is not within the range [-180.0, - * 180.0) or is Double.NaN - * @return a string representation of the coordinate in a representation indicated by - * the parameter - * @see #convert(String) - */ - public static String convert(double coordinate, int outputType) - throws IllegalArgumentException { - if ((coordinate < -180.0) || (coordinate >= 180.0) || (coordinate != coordinate)) - throw new IllegalArgumentException(); - - // 14 is max length, example: -123:12:12.123 - StringBuilder sb = new StringBuilder(14); - - if (coordinate < 0) - { - coordinate = -coordinate; - sb.append("-"); - } - - int r; - switch (outputType) - { - case DD_MM: - { - //convert to milli-minutes - r = (int)(coordinate * 60000 + 0.5); - sb.append(r / 60000); - break; - } - case DD_MM_SS: - { - //convert to milli-seconds - r = (int)(coordinate * 3600000 + 0.5); - sb.append(r / 3600000); - sb.append(':'); - - sb.append((char)('0' + r / 600000 % 6)); - sb.append((char)('0' + r / 60000 % 10)); - break; - } - default: - throw new IllegalArgumentException(); - } - - sb.append(':'); - sb.append((char)('0' + r / 10000 % 6)); - sb.append((char)('0' + r / 1000 % 10)); - - r = r % 1000; - if (r != 0) - { - sb.append('.'); - do - { - sb.append((char)('0' + r / 100)); - r = r * 10 % 1000; - } while (r != 0); - } - - return sb.toString(); - } - - /** - * Takes an integer and removes trailing zeros. - * - * @param number - * must be positive - * @return the number as a String, with trailing zeros removed. Returns null if the - * number was zero or negative. - */ - private static String dropTrailingZeros(int number) { - if (number <= 0) - return null; - while ((number % 10) == 0) { - number = number / 10; - } - return Integer.toString(number); - } - - /** - * Converts a String representation of a coordinate into the double representation as - * used in this API. There are two string syntaxes supported: - *

- * 1. Degrees, minutes, seconds and decimal fractions of seconds. This is expressed as - * a string complying with the following BNF definition where the degrees are within - * the range [-179, 179] and the minutes and seconds are within the range [0, 59], or - * the degrees is -180 and the minutes, seconds and decimal fractions are 0: - *

- * coordinate = degrees ":" minutes ":" seconds "." - * decimalfrac | degrees ":" minutes ":" seconds | degrees - * ":" minutes
- * degrees = degreedigits | "-" degreedigits
- * degreedigits = digit | nonzerodigit digit | "1" digit digit
- * minutes = minsecfirstdigit digit
- * seconds = minsecfirstdigit digit
- * decimalfrac = 1*3digit
- * digit = "0" | "1" | "2" | "3" | - * "4" | "5" | "6" | "7" | "8" | - * "9"
- * nonzerodigit = "1" | "2" | "3" | "4" | - * "5" | "6" | "7" | "8" | "9"
- * minsecfirstdigit = "0" | "1" | "2" | "3" | - * "4" | "5"
- *

- * 2. Degrees, minutes and decimal fractions of minutes. This is expressed as a string - * complying with the following BNF definition where the degrees are within the range - * [-179, 179] and the minutes are within the range [0, 59], or the degrees is -180 - * and the minutes and decimal fractions are 0: - *

- * coordinate = degrees ":" minutes "." decimalfrac | degrees - * ":" minutes
degrees = degreedigits | "-" degreedigits
- * degreedigits = digit | nonzerodigit digit | "1" digit digit
minutes = - * minsecfirstdigit digit
decimalfrac = 1*5digit
digit = "0" | - * "1" | "2" | "3" | "4" | "5" | - * "6" | "7" | "8" | "9"
nonzerodigit = - * "1" | "2" | "3" | "4" | "5" | - * "6" | "7" | "8" | "9"
- * minsecfirstdigit = "0" | "1" | "2" | "3" | - * "4" | "5" - *

- * For example, for the double value of the coordinate 61.51d, the corresponding - * syntax 1 string is "61:30:36" and the corresponding syntax 2 string is "61:30.6". - * - * @param coordinate - * a String in either of the two representation specified above - * @return a double value with decimal degrees that matches the string representation - * given as the parameter - * @throws IllegalArgumentException - * if the coordinate input parameter does not comply with the defined - * syntax for the specified types - * @throws NullPointerException - * if the coordinate string is null convert - */ - // TODO: This method similar to NMEASentence.degreesMintoDegrees(). Use that? - public static double convert(String coordinate) - throws IllegalArgumentException, NullPointerException { - /* - * A much more academic way to do this would be to generate some tree-based parser - * code using the BNF definition, but that seems a little too heavyweight for such - * short strings. - */ - if (coordinate == null) - throw new NullPointerException(); - - /* - * We don't have Java 5 regex or split support in Java 1.3, making this task a bit - * of a pain to code. - */ - - /* - * First we check that all the characters are valid, whilst also counting the - * number of colons and decimal points (we check that colons do not follow - * decimals). This allows us to know what type the string is. - */ - int length = coordinate.length(); - int colons = 0; - int decimals = 0; - for (int i = 0; i < length; i++) { - char element = coordinate.charAt(i); - if (!convertIsValidChar(element)) - throw new IllegalArgumentException(); - if (element == ':') { - if (decimals > 0) - throw new IllegalArgumentException(); - colons++; - } else if (element == '.') { - decimals++; - if (decimals > 1) - throw new IllegalArgumentException(); - } - } - - /* - * Then we break the string into its components and parse the individual pieces - * (whilst also doing bounds checking). Code looks ugly because there is a lot of - * Exception throwing for bad syntax. - */ - String[] parts = convertSplit(coordinate); - - try { - double out = 0.0; - // the first 2 parts are the same, regardless of type - int degrees = Integer.valueOf(parts[0]).intValue(); - if ((degrees < -180) || (degrees > 179)) - throw new IllegalArgumentException(); - boolean negative = false; - if (degrees < 0) { - negative = true; - degrees = Math.abs(degrees); - } - - out += degrees; - - int minutes = Integer.valueOf(parts[1]).intValue(); - if ((minutes < 0) || (minutes > 59)) - throw new IllegalArgumentException(); - out += minutes * 0.1 / 6; - - if (colons == 2) { - // type 1 - int seconds = Integer.valueOf(parts[2]).intValue(); - if ((seconds < 0) || (seconds > 59)) - throw new IllegalArgumentException(); - // degrees:minutes:seconds - out += seconds * 0.01 / 36; - if (decimals == 1) { - // degrees:minutes:seconds.decimalfrac - double decimalfrac = Double.valueOf("0." + parts[3]) - .doubleValue(); - // note that spec says this should be 1*3digit, but we don't - // restrict the digit count - if ((decimalfrac < 0) || (decimalfrac >= 1)) - throw new IllegalArgumentException(); - out += decimalfrac * 0.01 / 36; - } - } else if ((colons == 1) && (decimals == 1)) { - // type 2 - // degrees:minutes.decimalfrac - double decimalfrac = Double.valueOf("0." + parts[2]) - .doubleValue(); - // note that spec says this should be 1*5digit, but we don't - // restrict the digit count - if ((decimalfrac < 0) || (decimalfrac >= 1)) - throw new IllegalArgumentException(); - out += decimalfrac * 0.1 / 6; - } else - throw new IllegalArgumentException(); - - if (negative) { - out = -out; - } - - // do a final check on bounds - if ((out < -180.0) || (out >= 180.0)) - throw new IllegalArgumentException(); - return out; - } catch (NumberFormatException e) { - throw new IllegalArgumentException(); - } - } - - /** - * Helper method for {@link #convert(String)} - * - * @param element - * @return - */ - private static boolean convertIsValidChar(char element) { - if ((element == '-') || (element == ':') || (element == '.') - || Character.isDigit(element)) - return true; - return false; - } - - /** - * Helper method for {@link #convert(String)} - * - * @param in - * @return - */ - private static String[] convertSplit(String in) - throws IllegalArgumentException { - Vector parts = new Vector(4); - - int start = 0; - int length = in.length(); - for (int i = 0; i <= length; i++) { - if ((i == length) || (in.charAt(i) == ':') || (in.charAt(i) == '.')) { - // syntax checking - if (start - i == 0) - throw new IllegalArgumentException(); - String part = in.substring(start, i); - parts.addElement(part); - start = i + 1; - } - } - - // syntax checking - if ((parts.size() < 2) || (parts.size() > 4)) - throw new IllegalArgumentException(); - // return an array - String[] partsArray = new String[parts.size()]; - Enumeration en = parts.elements(); - for (int i = 0; en.hasMoreElements(); i++) { - partsArray[i] = en.nextElement(); - } - return partsArray; - } - -/***********************************/ - - /** - * - * Calculates the geodetic distance between the two points according - * to the ellipsoid model of WGS84. Altitude is neglected from calculations. - * - * The implementation shall calculate this as exactly as it can. - * However, it is required that the result is within 0.36% of - * the correct result. - * - * @param to the point to calculate the geodetic to - * @return the distance in meters - */ - public double distance(Coordinates to){ - if(to == null){ - throw new NullPointerException(); - }else{ - // TODO: Is there some way to make it not recalculate if it already - // calculated for these coordinates? Keep in mind coordinates can change. - calculateDistanceAndAzimuth(getLatitude(), getLongitude(), to.getLatitude(), to.getLongitude()); - return calculatedDistance; - } - } - - private static void calculateDistanceAndAzimuth(double d, double d1, double d2, double d3){ - // TODO: This code is huge. Can it be minimized? - double d4 = Math.toRadians(d); - double d5 = Math.toRadians(d1); - double d6 = Math.toRadians(d2); - double d7 = Math.toRadians(d3); - double d8 = 0.0033528106647474805D; - // TODO: Why are these given 0 values? - double d9 = 0.0D; - double d10 = 0.0D; - double d20 = 0.0D; - double d22 = 0.0D; - double d24 = 0.0D; - double d25 = 0.0D; - double d26 = 0.0D; - double d28 = 0.0D; - double d29 = 0.0D; - double d30 = 0.0D; - double d31 = 0.0D; - double d32 = 0.0D; - double d33 = 5.0000000000000003E-10D; - int i = 1; - byte byte0 = 100; - if(d4 == d6 && (d5 == d7 || Math.abs(Math.abs(d5 - d7) - 6.2831853071795862D) < d33)) - { - calculatedDistance = 0.0F; - calculatedAzimuth = 0.0F; - return; - } - - // TODO: Use our version of Math.PI throughout, including 2pi. - if(d4 + d6 == 0.0D && Math.abs(d5 - d7) == 3.1415926535897931D) - d4 += 1.0000000000000001E-05D; - double d11 = 1.0D - d8; - double d12 = d11 * Math.tan(d4); - double d13 = d11 * Math.tan(d6); - double d14 = 1.0D / Math.sqrt(1.0D + d12 * d12); - double d15 = d14 * d12; - double d16 = 1.0D / Math.sqrt(1.0D + d13 * d13); - double d17 = d14 * d16; - double d18 = d17 * d13; - double d19 = d18 * d12; - d9 = d7 - d5; - - for(d32 = d9 + 1.0D; i < byte0 && Math.abs(d32 - d9) > d33; d9 = ((1.0D - d31) * d9 * d8 + d7) - d5) - { - i++; - double d21 = Math.sin(d9); - double d23 = Math.cos(d9); - d12 = d16 * d21; - d13 = d18 - d15 * d16 * d23; - d24 = Math.sqrt(d12 * d12 + d13 * d13); - d25 = d17 * d23 + d19; - d10 = Math.atan2(d24, d25); - double d27 = (d17 * d21) / d24; - d28 = 1.0D - d27 * d27; - d29 = 2D * d19; - if(d28 > 0.0D) - d29 = d25 - d29 / d28; - d30 = -1D + 2D * d29 * d29; - d31 = (((-3D * d28 + 4D) * d8 + 4D) * d28 * d8) / 16D; - d32 = d9; - d9 = ((d30 * d25 * d31 + d29) * d24 * d31 + d10) * d27; - } - - double d34 = mod(Math.atan2(d12, d13), 6.2831853071795862D); - d9 = Math.sqrt((1.0D / (d11 * d11) - 1.0D) * d28 + 1.0D); - d9++; - d9 = (d9 - 2D) / d9; - d31 = ((d9 * d9) / 4D + 1.0D) / (1.0D - d9); - d32 = (d9 * d9 * 0.375D - 1.0D) * d9; - d9 = d30 * d25; - - double d35 = ((((((d24 * d24 * 4D - 3D) * (1.0D - d30 - d30) * d29 * d32) / 6D - d9) * d32) / 4D + d29) * d24 * d32 + d10) * d31 * 6378137D * d11; - if((double)Math.abs(i - byte0) < d33) - { - calculatedDistance = (0.0F / 0.0F); - calculatedAzimuth = (0.0F / 0.0F); - return; - } - d34 = (180D * d34) / 3.1415926535897931D; - calculatedDistance = (float)d35; - calculatedAzimuth = (float)d34; - if(d == 90D) - calculatedAzimuth = 180F; - else - if(d == -90D) - calculatedAzimuth = 0.0F; - } - - // TODO: A mod method? Why not use % - private static double mod(double d, double d1){ - return d - d1 * Math.floor(d / d1); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/GGASentence.java b/ev3classes/src/main/java/lejos/hardware/gps/GGASentence.java deleted file mode 100644 index 93ff1df..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/GGASentence.java +++ /dev/null @@ -1,290 +0,0 @@ -package lejos.hardware.gps; - -import java.util.NoSuchElementException; - -/** - * This class has been designed to manage a GGA Sentence - * - * GGA - essential fix data which provide 3D location and accuracy data. - * - * $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47 - * - * Where: - * GGA Global Positioning System Fix Data - * 123519 Fix taken at 12:35:19 UTC - * 4807.038,N Latitude 48 deg 07.038' N - * 01131.000,E Longitude 11 deg 31.000' E - * 1 Fix quality: 0 = invalid - * 1 = GPS fix (SPS) - * 2 = DGPS fix - * 3 = PPS fix - * 4 = Real Time Kinematic - * 5 = Float RTK - * 6 = estimated (dead reckoning) (2.3 feature) - * 7 = Manual input mode - * 8 = Simulation mode - * 08 Number of satellites being tracked - * 0.9 Horizontal dilution of position - * 545.4,M Altitude, Meters, above mean sea level - * 46.9,M Height of geoid (mean sea level) above WGS84 - * ellipsoid - * (empty field) time in seconds since last DGPS update - * (empty field) DGPS station ID number - * *47 the checksum data, always begins with * - * - * @author Juan Antonio Brenha Moral - * - * Added changes by Alan M Gilkes - Nov 12th 2014 - Lawrie Griffiths - * - */ - -public class GGASentence extends NMEASentence { - - private double latitude = 0; - private double longitude = 0; - private String nmeaHeader = ""; - private int dateTimeOfFix = 0; - private char latitudeDirection; - private char longitudeDirection; - private int quality = 0; - private int satellitesTracked = 0; - private float hdop = 0; - private float altitude = 0; - private String altitudeUnits; - private float geoidalSeparation; - private String geoidalSeparationUnit; - - //Header - public static final String HEADER = "$GPGGA"; - - /** - * Any GPS Receiver gives Lat/Lon data in the following way: - * - * http://www.gpsinformation.org/dale/nmea.htm - * http://www.teletype.com/pages/support/Documentation/RMC_log_info.htm - * - * 4807.038,N Latitude 48 deg 07.038' N - * 01131.000,E Longitude 11 deg 31.000' E - * - * This data is necessary to convert to Decimal Degrees. - * - * Latitude values has the range: -90 <-> 90 - * Longitude values has the range: -180 <-> 180 - * - * @param DD_MM - * @param CoordinateType - * @return the degrees - */ - protected double degreesMinToDegreesDbl(String DD_MM,int CoordinateType) {//throws NumberFormatException - // This methods accept all strings of the format - // DDDMM.MMMM - // DDDMM - // MM.MMMM - // MM - - // check first character, rest is checked by parseInt/parseFloat - int len = DD_MM.length(); - if (len <= 0 || DD_MM.charAt(0) == '-') - throw new NumberFormatException(); - - int dotPosition = DD_MM.indexOf('.'); - if (dotPosition < 0) - dotPosition = len; - - int degrees; - double minutes; - if (dotPosition > 2) - { - degrees = Integer.parseInt(DD_MM.substring(0, dotPosition-2)); - // check first character of minutes since '-' is not allowed - // rest is checked by parseFloat - if (DD_MM.charAt(dotPosition-2) == '-') - throw new NumberFormatException(); - minutes = Double.parseDouble(DD_MM.substring(dotPosition-2)); - } - else - { - degrees = 0; - minutes = Double.parseDouble(DD_MM); - } - -// if(CoordenateType == NMEASentence.LATITUDE){ -// if((degrees >=0) && (degrees <=90)){ -// throw new NumberFormatException(); -// } -// }else{ -// if((degrees >=0) && (degrees <=180)){ -// throw new NumberFormatException(); -// } -// } - - return (double)(degrees + minutes * (double)(1.0 / 60.0)); - } - - /* - * GETTERS & SETTERS - */ - - /** - * Returns the NMEA header for this sentence. - */ - @Override - public String getHeader() { - return nmeaHeader;//The header actually read in when the sentence was parsed - } - - /** - * Get Latitude - * - */ - public double getLatitude() { - return latitude; - } - - /** - * Get Latitude Direction - * - * @return the latitude direction - */ - public char getLatitudeDirection(){ - return latitudeDirection; - } - - /** - * Get Longitude - * - */ - public double getLongitude() { - return longitude; - } - - /** - * Get Longitude Direction - * @return the longitude direction - */ - public char getLongitudeDirection(){ - return longitudeDirection; - } - - /** - * Get Altitude - * - * @return the altitude - */ - public float getAltitude(){ - return altitude; - } - - /** - * Returns the last time stamp retrieved from a satellite - * - * @return The time as a UTC integer. 123519 = 12:35:19 UTC - */ - public int getTime(){ - return dateTimeOfFix; - } - - /** - * Returns the number of satellites being tracked to - * determine the coordinates. - * - * @return Number of satellites e.g. 8 - */ - public int getSatellitesTracked() { - return satellitesTracked; - } - - /** - * Get GPS Quality Data - * - * @return the fix quality - */ - public int getFixQuality(){ - return quality; - } - - /** - * Get Horizontal Dilution of Precision (HDOP) - * - * @return the hdop - */ - public float getHDOP(){ - return hdop; - } - - - /** - * Method used to parse a GGA Sentence - */ - public void parse(String sentence) { - - String[] parts = sentence.split(","); - - try{ - //Processing GGA data - - nmeaHeader = parts[0]; - - if (parts[1].length() == 0) { - dateTimeOfFix = 0; - } else { - dateTimeOfFix = Math.round(Float.parseFloat(parts[1])); - } - - if (isNumeric(parts[2])) { - latitude = degreesMinToDegreesDbl(parts[2],NMEASentence.LATITUDE); - } else { - latitude = 0.0; - } - - latitudeDirection = parts[3].charAt(0); - - if (isNumeric(parts[4])) { - longitude = degreesMinToDegreesDbl(parts[4],NMEASentence.LONGITUDE); - } else { - longitude = 0.0; - } - - longitudeDirection = parts[5].charAt(0); - - if (longitudeDirection != 'E') { - longitude = -longitude; - } - - if (latitudeDirection != 'N') { - latitude = -latitude; - } - - if (parts[6].length() == 0) { - quality = 0; - } else{ - quality = Math.round(Float.parseFloat(parts[6]));//Fix quality - } - - if (parts[7].length() == 0) { - satellitesTracked = 0; - } else{ - satellitesTracked = Math.round(Float.parseFloat(parts[7])); - } - - if (parts[8].length() == 0) { - hdop = 0; - } else { - hdop = Float.parseFloat(parts[8]);//Horizontal dilution of position - } - - if (isNumeric(parts[9])) { - altitude = Float.parseFloat(parts[9]); - } else{ - altitude = 0f; - } - } catch(NoSuchElementException e) { - //System.err.println("GGASentence: NoSuchElementException"); - } catch(NumberFormatException e) { - //System.err.println("GGASentence: NumberFormatException"); - } catch(Exception e){ - //System.err.println("GGASentence: Exception"); - } - }//End parse - -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/GPS.java b/ev3classes/src/main/java/lejos/hardware/gps/GPS.java deleted file mode 100644 index c4de125..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/GPS.java +++ /dev/null @@ -1,182 +0,0 @@ -package lejos.hardware.gps; - -import java.io.InputStream; -import java.util.Date; - -/** - * This class manages data received from a GPS Device. - * GPS Class manages the following NMEA Sentences: - * - * GPRMC - * GPGSV - * GPGSA - * GPGGA (superclass) - * GPVTG (superclass) - * - * @author BB - * @author Juan Antonio Brenha Moral - * - */ -/* - * DEVELOPER NOTES: More NMEA sentence types that can be added if there is demand for them: - * http://www.gpsinformation.org/dale/nmea.htm - */ -public class GPS extends SimpleGPS { - - //Classes which manages GGA, RMC, VTG, GSV, GSA Sentences - private RMCSentence rmcSentence; - //TODO device sends a sequence of complementary gsv sentences - // this class only remembers the last one - private GSVSentence gsvSentence; - - //Date Object with use GGA & RMC Sentence - private Date date; - - /** - * The constructor. It needs an InputStream - * - * @param in An input stream from the GPS receiver - */ - public GPS(InputStream in) { - super(in); - rmcSentence = new RMCSentence(); - gsvSentence = new GSVSentence(); - - date = new Date(); - } - - - /* GETTERS & SETTERS */ - - /** - * Return Compass Degrees - * in a range: 0.0-359.9 - * - * @return the compass degrees - */ - public float getCompassDegrees(){ - return rmcSentence.getCompassDegrees(); - } - - /** - * Return a Date Object with data from GGA and RMC NMEA Sentence - * - * @return the date - */ - public Date getDate(){ - // TODO: Would be more proper to return a new Date object instead of recycled Date. - updateDate(); - updateTime(); - return date; - } - - /** - * - * Get NMEA Satellite. The satellite list is retrieved from the almanac data. Satellites are - * ordered by their elevation: highest elevation (index 0) -> lowest elevation. - * - * @param index the satellite index - * @return the NMEASaltellite object for the selected satellite - */ - public Satellite getSatellite(int index){ - Satellite s = gsvSentence.getSatellite(index); - // Compare getPRN() with this satellite, fill in setTracked(): - // TODO: This fails because most satellites are set to 0 when this is called. Not synced yet. - boolean tracked = false; - int [] prns = getPRN(); - for(int i=0;i0) { - int hh = timeStamp / 10000; - int mm = (timeStamp / 100) % 100; - int ss = timeStamp % 100; - - date.setHours(hh); - date.setMinutes(mm); - date.setSeconds(ss); - } - } - - /** - * Update Date values - */ - private void updateDate(){ - int dateStamp = rmcSentence.getDate(); - - if(dateStamp > 0) { - int dd = dateStamp / 10000; - int mm = (dateStamp / 100) % 100; - int yy = dateStamp % 100; - - date.setDate(dd); - date.setMonth(mm); - date.setYear(yy); - } - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/gps/GPSListener.java b/ev3classes/src/main/java/lejos/hardware/gps/GPSListener.java deleted file mode 100644 index afc8b5a..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/GPSListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package lejos.hardware.gps; - - -import java.util.EventListener; - -/** - * This is the interface to manage events with GPS - * - * @author Juan Antonio Brenha Moral - * - */ - -public interface GPSListener extends EventListener{ - - // TODO: Probably just one sentenceReceived() method, with NMEA sentence. - // Compare GGASentence.HEADER with the NMEASentence.getHeader() using .equals; - /** - * Called whenever a new NMEA sentence is produced by the GPS receiver. - * To identify the type of NMEA sentence received, use NMEASentence.getHeader(). - * Then cast the sentence into the appropriate type. e.g. (GGASentence)sen - */ - public void sentenceReceived(NMEASentence sen); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/GSASentence.java b/ev3classes/src/main/java/lejos/hardware/gps/GSASentence.java deleted file mode 100644 index f6d7996..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/GSASentence.java +++ /dev/null @@ -1,195 +0,0 @@ -package lejos.hardware.gps; - -import java.util.NoSuchElementException; -import java.util.StringTokenizer; - -/** - * This class has been designed to manage a GSA Sentence - * - * GPS DOP and active satellites - * - * eg1. $GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C - * eg2. $GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35 - * - * 1 = Mode: - * M=Manual, forced to operate in 2D or 3D - * A=Automatic, 3D/2D - * 2 = Mode: - * 1=Fix not available - * 2=2D - * 3=3D - * 3-14 = IDs of SVs used in position fix (null for unused fields) - * 15 = PDOP - * 16 = HDOP - * 17 = VDOP - * - * @author Juan Antonio Brenha Moral - * - * Added changes by Alan M Gilkes - Nov 12th 2014 - Lawrie Griffiths - * - */ - -public class GSASentence extends NMEASentence{ - //GSA - private String nmeaHeader = ""; - private String mode = ""; - private int modeValue = 0; - private final int MAXIMUMSV = 12; - private int[] SV; - private float PDOP = 0f; - private float HDOP = 0f; - private float VDOP = 0f; - - //Header - public static final String HEADER = "$GPGSA"; - - /** - * Constructor - */ - public GSASentence(){ - SV = new int[MAXIMUMSV]; - } - - /** - * Returns the NMEA header for this sentence. - */ - @Override - public String getHeader() { - return HEADER; - } - - /** - * Return Mode1. - * Mode1 can receive the following values: - * - * M=Manual, forced to operate in 2D or 3D - * A=Automatic, 3D/2D - * - */ - public String getMode(){ - return mode; - } - - /** - * Return Mode2. - * Mode1 can receive the following values: - * - * 1=Fix not available - * 2=2D - * 3=3D - * - */ - public int getModeValue(){ - return modeValue; - } - - /** - * Return an Array with Satellite IDs - * - * @return an array of satellite ids - */ - public int[] getPRN(){ - return SV; - } - - /** - * Return PDOP - * - * @return the PDOP - */ - public float getPDOP(){ - return PDOP; - } - - /** - * Return HDOP - * - * @return the HDOP - */ - public float getHDOP(){ - return HDOP; - } - - /** - * Return VDOP - * - * @return the VDOP - */ - public float getVDOP(){ - return VDOP; - } - - /** - * Method used to parse a GGA Sentence - */ - public void parse(String sentence){ - - //TODO StringTokenizer must not be used to parse NMEA sentences since it doesn't return empty tokens - StringTokenizer st = new StringTokenizer(sentence,","); - - try{ - - //Extracting data from a GSA Sentence - - String part1 = st.nextToken();//NMEA header - String part2 = st.nextToken();//mode - String part3 = st.nextToken();//modeValue - - //Processing GSA data - - nmeaHeader = part1; - mode = part2; - - if(part3 == null){ - modeValue = 0; - }else{ - if(part3.length() == 0){ - modeValue = 0; - }else{ - modeValue = Math.round(Float.parseFloat(part3)); - } - } - - for(int i=0;i<12;i++){ - String part = st.nextToken(); - if(part.length() > 0){ - SV[i] = Integer.parseInt(part); - }else{ - SV[i] = 0; - } - } - - String part16 = st.nextToken();//PDOP - String part17 = st.nextToken();//HDOP - String part18 = st.nextToken();//VDOP - - st = null; - - if(part16.length() == 0){ - PDOP = 0; - }else{ - PDOP = Float.parseFloat(part16); - } - - if(part17.length() == 0){ - HDOP = 0; - }else{ - HDOP = Float.parseFloat(part17); - } - - if(part18.length() == 0){ - VDOP = 0; - }else{ - VDOP = Float.parseFloat(part18); - } - - }catch(NoSuchElementException e){ - //System.err.println("GSASentence: NoSuchElementException"); - }catch(NumberFormatException e){ - //System.err.println("GSASentence: NumberFormatException"); - }catch(Exception e){ - //System.err.println("GSASentence: Exception"); - } - - }//End parse -}//End Class \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/gps/GSVSentence.java b/ev3classes/src/main/java/lejos/hardware/gps/GSVSentence.java deleted file mode 100644 index b8c55aa..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/GSVSentence.java +++ /dev/null @@ -1,260 +0,0 @@ -package lejos.hardware.gps; - -import java.util.NoSuchElementException; - -/** - * This class has been designed to manage a GSV Sentence - * - * GPS Satellites in view - * - * eg. $GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74 - * $GPGSV,3,2,11,14,25,170,00,16,57,208,39,18,67,296,40,19,40,246,00*74 - * $GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D - * - * - * $GPGSV,1,1,13,02,02,213,,03,-3,000,,11,00,121,,14,13,172,05*67 - * - * 1 = Total number of messages of this type in this cycle - * 2 = Message number - * 3 = Total number of SVs in view - * 4 = SV PRN number - * 5 = Elevation in degrees, 90 maximum - * 6 = Azimuth, degrees from true north, 000 to 359 - * 7 = SNR, 00-99 dB (null when not tracking) - * 8-11 = Information about second SV, same as field 4-7 - * 12-15= Information about third SV, same as field 4-7 - * 16-19= Information about fourth SV, same as field 4-7 - * - * @author Juan Antonio Brenha Moral - * - */ -public class GSVSentence extends NMEASentence{ - - //GGA - private String nmeaHeader = ""; - private int satellitesInView = 0; - private final int MAXIMUMSATELLITES = 4; - private Satellite ns1; - private Satellite ns2; - private Satellite ns3; - private Satellite ns4; - - //Header - public static final String HEADER = "$GPGSV"; - - /* - * Constructor - */ - public GSVSentence(){ - ns1 = new Satellite(); - ns2 = new Satellite(); - ns3 = new Satellite(); - ns4 = new Satellite(); - } - - - /* - * GETTERS & SETTERS - */ - - /** - * Returns the NMEA header for this sentence. - */ - @Override - public String getHeader() { - return HEADER; - } - - /** - * Returns the number of satellites being tracked to - * determine the coordinates. - * - * @return Number of satellites e.g. 8 - */ - public int getSatellitesInView() { - return satellitesInView; - } - - /** - * Return a NMEA Satellite object - * - * @param index - * @return a NMEA satellite object - */ - public Satellite getSatellite(int index){ - Satellite ns = new Satellite(); - if(index == 0){ - ns = ns1; - }else if(index == 1){ - ns = ns2; - }else if(index == 2){ - ns = ns3; - }else if(index == 3){ - ns = ns4; - } - return ns; - } - - - /** - * Method used to parse a GSV Sentence - */ - public void parse(String sentence){ - - String[] parts = sentence.split(","); - - int PRN = 0; - int elevation = 0; - int azimuth = 0; - int SNR = 0; - - try{ - - //Extracting data from a GSV Sentence - - //TODO Length of GSV Sentence varies. - // See http://www.gpsinformation.org/dale/nmea.htm for an example - - nmeaHeader = parts[0]; - - if (parts[3].length() == 0) { - satellitesInView = 0; - } else { - satellitesInView = Math.round(Float.parseFloat(parts[3])); - } - - if(satellitesInView > 0) { - - //SAT 1 - - if(parts[4].length() == 0) { - PRN = 0; - } else{ - PRN = Math.round(Float.parseFloat(parts[4])); - } - - if(parts[5].length() == 0) { - elevation = 0; - } else { - elevation = Math.round(Float.parseFloat(parts[5])); - } - - if (parts[6].length() == 0) { - azimuth = 0; - } else { - azimuth = Math.round(Float.parseFloat(parts[6])); - } - - if (parts[7].length() == 0) { - SNR = 0; - } else { - SNR = Math.round(Float.parseFloat(parts[7])); - } - - ns1.setPRN(PRN); - ns1.setElevation(elevation); - ns1.setAzimuth(azimuth); - ns1.setSignalNoiseRatio(SNR); - - //SAT 2 - - if (parts[8].length() == 0) { - PRN = 0; - } else { - PRN = Math.round(Float.parseFloat(parts[8])); - } - - if (parts[9].length() == 0) { - elevation = 0; - } else { - elevation = Math.round(Float.parseFloat(parts[9])); - } - - if (parts[10].length() == 0) { - azimuth = 0; - } else { - azimuth = Math.round(Float.parseFloat(parts[10])); - } - - if (parts[11].length() == 0) { - SNR = 0; - } else { - SNR = Math.round(Float.parseFloat(parts[11])); - } - - ns2.setPRN(PRN); - ns2.setElevation(elevation); - ns2.setAzimuth(azimuth); - ns2.setSignalNoiseRatio(SNR); - - //SAT 3 - - if (parts[12].length() == 0) { - PRN = 0; - } else { - PRN = Math.round(Float.parseFloat(parts[12])); - } - - if (parts[13].length() == 0) { - elevation = 0; - } else { - elevation = Math.round(Float.parseFloat(parts[13])); - } - - if (parts[14].length() == 0) { - azimuth = 0; - } else { - azimuth = Math.round(Float.parseFloat(parts[14])); - } - - if (parts[15].length() == 0) { - SNR = 0; - } else { - SNR = Math.round(Float.parseFloat(parts[15])); - } - - ns3.setPRN(PRN); - ns3.setElevation(elevation); - ns3.setAzimuth(azimuth); - ns3.setSignalNoiseRatio(SNR); - - // SAT 4 - - if (parts[16].length() == 0) { - PRN = 0; - } else { - PRN = Math.round(Float.parseFloat(parts[16])); - } - - if (parts[17].length() == 0) { - elevation = 0; - } else { - elevation = Math.round(Float.parseFloat(parts[17])); - } - - if (parts[18].length() == 0) { - azimuth = 0; - } else { - azimuth = Math.round(Float.parseFloat(parts[18])); - } - - if (parts[19].length() == 0) { - SNR = 0; - } else { - SNR = Math.round(Float.parseFloat(parts[19])); - } - - ns4.setPRN(PRN); - ns4.setElevation(elevation); - ns4.setAzimuth(azimuth); - ns4.setSignalNoiseRatio(SNR); - } - } catch(NoSuchElementException e) { - //System.err.println("GSVSentence: NoSuchElementException"); - } catch(NumberFormatException e) { - //System.err.println("GSVSentence: NumberFormatException"); - } catch(Exception e) { - //System.err.println("GSVSentence: Exception"); - } - }//End parse -}//End class diff --git a/ev3classes/src/main/java/lejos/hardware/gps/NMEASentence.java b/ev3classes/src/main/java/lejos/hardware/gps/NMEASentence.java deleted file mode 100644 index ec31f08..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/NMEASentence.java +++ /dev/null @@ -1,109 +0,0 @@ -package lejos.hardware.gps; - -/** - * Class designed to manage all NMEA Sentence. - * - * GGA and RMC Sentence needs to validate data. - * This class has methods to validate receivedad data - * - * @author Juan Antonio Brenha Moral - * @author BB - * - */ -abstract public class NMEASentence { - - public static final int LATITUDE = 0; - public static final int LONGITUDE = 1; - - /** - * Retrieve the header constant for this sentence. - * @return The NMEA header string ($GPGGA, $GPVTG, etc...) - */ - // TODO: Maybe getSentenceType()? - // TODO: Should it return the $ too, or maybe have a list of constants? - abstract public String getHeader(); - - /** - * Abstract method to parse out all relevant data from the nmeaSentence. - */ - abstract protected void parse(String sentence); - - /** - * Any GPS Receiver gives Lat/Lon data in the following way: - * - * http://www.gpsinformation.org/dale/nmea.htm - * http://www.teletype.com/pages/support/Documentation/RMC_log_info.htm - * - * 4807.038,N Latitude 48 deg 07.038' N - * 01131.000,E Longitude 11 deg 31.000' E - * - * This data is necessary to convert to Decimal Degrees. - * - * Latitude values has the range: -90 <-> 90 - * Longitude values has the range: -180 <-> 180 - * - * @param DD_MM - * @param CoordinateType - * @return the degrees - */ - protected float degreesMinToDegrees(String DD_MM,int CoordinateType) {//throws NumberFormatException - // This methods accept all strings of the format - // DDDMM.MMMM - // DDDMM - // MM.MMMM - // MM - - // check first character, rest is checked by parseInt/parseFloat - int len = DD_MM.length(); - if (len <= 0 || DD_MM.charAt(0) == '-') - throw new NumberFormatException(); - - int dotPosition = DD_MM.indexOf('.'); - if (dotPosition < 0) - dotPosition = len; - - int degrees; - float minutes; - if (dotPosition > 2) - { - degrees = Integer.parseInt(DD_MM.substring(0, dotPosition-2)); - // check first character of minutes since '-' is not allowed - // rest is checked by parseFloat - if (DD_MM.charAt(dotPosition-2) == '-') - throw new NumberFormatException(); - minutes = Float.parseFloat(DD_MM.substring(dotPosition-2)); - } - else - { - degrees = 0; - minutes = Float.parseFloat(DD_MM); - } - -// if(CoordenateType == NMEASentence.LATITUDE){ -// if((degrees >=0) && (degrees <=90)){ -// throw new NumberFormatException(); -// } -// }else{ -// if((degrees >=0) && (degrees <=180)){ -// throw new NumberFormatException(); -// } -// } - - return degrees + minutes * (float)(1.0 / 60.0); - } - - //Idea - //http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Java - public final boolean isNumeric(final String s) { - if (s == null || s.isEmpty()) return false; - for (int x = 0; x < s.length(); x++) { - final char c = s.charAt(x); - if (x == 0 && (c == '-')) continue; // negative - if ((c >= '0') && (c <= '9')) continue; // 0 - 9 - if (c == '.') continue; // float or double values - return false; // invalid - } - return true; // valid - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/RMCSentence.java b/ev3classes/src/main/java/lejos/hardware/gps/RMCSentence.java deleted file mode 100644 index be2dc2c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/RMCSentence.java +++ /dev/null @@ -1,289 +0,0 @@ -package lejos.hardware.gps; - -import java.util.NoSuchElementException; - - -/** - * RMC is a Class designed to manage RMC Sentences from a NMEA GPS Receiver - * - * RMC - NMEA has its own version of essential gps pvt (position, velocity, time) data. It is called RMC, The Recommended Minimum, which will look similar to: - * - * $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A - * - * Where: - * RMC Recommended Minimum sentence C - * 123519 Fix taken at 12:35:19 UTC - * A Status A=active or V=Void. - * 4807.038,N Latitude 48 deg 07.038' N - * 01131.000,E Longitude 11 deg 31.000' E - * 022.4 Speed over the ground in knots - * 084.4 Track angle in degrees True - * 230394 Date - 23rd of March 1994 - * 003.1,W Magnetic Variation - * *6A The checksum data, always begins with * - * - * @author Juan Antonio Brenha Moral - * - * Added changes by Alan M Gilkes - Nov 12th 2014 - Lawrie Griffiths - * - */ - -public class RMCSentence extends NMEASentence { - - //RMC Sentence - private String nmeaHeader = ""; - private int dateTimeOfFix = 0; - private final int DATETIMELENGTH = 6; - private String status = ""; - private final String ACTIVE = "A"; - private final String VOID = "V"; - private double latitude = 0; - private String latitudeDirection = ""; - private double longitude = 0; - private String longitudeDirection = ""; - private final float KNOT = 1.852f; - private float groundSpeed;//In knots - private float compassDegrees; - private int dateOfFix = 0; - private float magneticVariation = 0f; - private String magneticVariationLetter = ""; - - private float speed;//In Kilometers per hour - - //Header - public static final String HEADER = "$GPRMC"; - - /** - * Any GPS Receiver gives Lat/Lon data in the following way: - * - * http://www.gpsinformation.org/dale/nmea.htm - * http://www.teletype.com/pages/support/Documentation/RMC_log_info.htm - * - * 4807.038,N Latitude 48 deg 07.038' N - * 01131.000,E Longitude 11 deg 31.000' E - * - * This data is necessary to convert to Decimal Degrees. - * - * Latitude values has the range: -90 <-> 90 - * Longitude values has the range: -180 <-> 180 - * - * @param DD_MM - * @param CoordinateType - * @return the degrees - */ - protected double degreesMinToDegreesDbl(String DD_MM,int CoordinateType) {//throws NumberFormatException - // This methods accept all strings of the format - // DDDMM.MMMM - // DDDMM - // MM.MMMM - // MM - - // check first character, rest is checked by parseInt/parseFloat - int len = DD_MM.length(); - if (len <= 0 || DD_MM.charAt(0) == '-') - throw new NumberFormatException(); - - int dotPosition = DD_MM.indexOf('.'); - if (dotPosition < 0) - dotPosition = len; - - int degrees; - double minutes; - if (dotPosition > 2) - { - degrees = Integer.parseInt(DD_MM.substring(0, dotPosition-2)); - // check first character of minutes since '-' is not allowed - // rest is checked by parseFloat - if (DD_MM.charAt(dotPosition-2) == '-') - throw new NumberFormatException(); - minutes = Double.parseDouble(DD_MM.substring(dotPosition-2)); - } - else - { - degrees = 0; - minutes = Double.parseDouble(DD_MM); - } - -// if(CoordenateType == NMEASentence.LATITUDE){ -// if((degrees >=0) && (degrees <=90)){ -// throw new NumberFormatException(); -// } -// }else{ -// if((degrees >=0) && (degrees <=180)){ -// throw new NumberFormatException(); -// } -// } - - return (double)(degrees + minutes * (double)(1.0 / 60.0)); - } - - /* - * GETTERS & SETTERS - */ - - /** - * Returns the NMEA header for this sentence. - */ - @Override - public String getHeader() { - return nmeaHeader; - } - - public String getStatus(){ - return status; - } - - /** - * Get Latitude - * - */ - public double getLatitude(){ - return latitude; - } - - /** - * Get Longitude - * - * @return the longitude - */ - public double getLongitude(){ - return longitude; - } - - /** - * Get Speed in Kilometers - * - * @return the speed - */ - public float getSpeed(){ - return speed; - } - - /** - * Get time in integer format - * - * @return the time - */ - public int getTime(){ - return dateTimeOfFix; - } - - /** - * Get date in integer format - * - * @return the date - */ - public int getDate(){ - return dateOfFix; - } - - /** - * Return compass value from GPS - * - * @return the compass heading - */ - public float getCompassDegrees(){ - return compassDegrees; - } - - /** - * Parse a RMC Sentence - * - * $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62 - */ - public void parse (String sentence) { - - String[] parts = sentence.split(","); - - try{ - //Processing RMC data - - nmeaHeader = parts[0];//$GPRMC - - if (parts[1].length() == 0) { - dateTimeOfFix = 0; - } else { - dateTimeOfFix = Math.round(Float.parseFloat(parts[1])); - } - - if (parts[2].equals(ACTIVE)) { - status = ACTIVE; - } else { - status = VOID; - } - - if (isNumeric(parts[3])) { - latitude = degreesMinToDegreesDbl(parts[3],NMEASentence.LATITUDE); - } else { - latitude = 0f; - } - - latitudeDirection = parts[4]; - - if (isNumeric(parts[5])) { - longitude = degreesMinToDegreesDbl(parts[5],NMEASentence.LONGITUDE); - } else { - longitude = 0f; - } - - longitudeDirection = parts[6]; - - if (longitudeDirection.equals("E") == false) { - longitude = -longitude; - } - - if (latitudeDirection.equals("N") == false) { - latitude = -latitude; - } - - if (parts[7].length() == 0) { - groundSpeed = 0f; - speed = 0f; - } else { - groundSpeed = Float.parseFloat(parts[7]); - - //Speed - if (groundSpeed > 0) { - // km/h = knots * 1.852 - speed = groundSpeed * KNOT; - } - - // A negative speed doesn't make sense. - if (speed < 0) { - speed = 0f; - } - } - - if (parts[8].length() == 0) { - compassDegrees = 0; - } else { - compassDegrees = Float.parseFloat(parts[8]); - } - - if (parts[9].length() == 0) { - dateOfFix = 0; - } else{ - dateOfFix = Math.round(Float.parseFloat(parts[9])); - } - - if (parts[10].length() == 0) { - magneticVariation = 0; - } else{ - magneticVariation = Float.parseFloat(parts[10]); - } - - if (parts[11].length() == 0) { - magneticVariationLetter = ""; - } else{ - magneticVariationLetter = parts[11]; - } - } catch(NoSuchElementException e) { - //System.err.println("RMCSentence: NoSuchElementException"); - } catch(NumberFormatException e) { - //System.err.println("RMCSentence: NumberFormatException"); - } catch(Exception e) { - //System.err.println("RMCSentence: Exception"); - } - }//End Parse - -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/Satellite.java b/ev3classes/src/main/java/lejos/hardware/gps/Satellite.java deleted file mode 100644 index 01fb8d8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/Satellite.java +++ /dev/null @@ -1,153 +0,0 @@ -package lejos.hardware.gps; - -/** - * This class models data extracted from NMEA GSV Sentence - * - * $GPGSV,1,1,13,02,02,213,,03,-3,000,,11,00,121,,14,13,172,05*67 - * - * 4 = SV PRN number - * 5 = Elevation in degrees, 90 maximum - * 6 = Azimuth, degrees from true north, 000 to 359 - * 7 = SNR, 00-99 dB (null when not tracking) - * - * You can find out more about a satellite by looking up the PRN number here: - * http://en.wikipedia.org/wiki/List_of_GPS_satellite_launches - * - * @author Juan Antonio Brenha Moral - * - */ -public class Satellite { - private int PRN = 0; - private int elevation = 0; - private int azimuth = 0; - private int SNR = 0; - private boolean tracked; - - /* - * Constructors - */ - - public Satellite() { - // - } - - /** - * Constructor which indicate information about: - * PRN, Elevation, Azimuth and SNR - * - * @param p - * @param e - * @param a - * @param s - */ - public Satellite(int p, int e, int a, int s) { - PRN = p; - elevation = e; - azimuth = a; - SNR = s; - } - - // TODO: getVehicleNumber() should be in here. SVN = Satellite Vehicle Number - - /* - * Getters & Setters - */ - - /** - * Return PRN number from a Satellite. PRN stands for Pseudo-Random Noise. The PRN is the - * index to the assigned pseudorandom number sequence used to encode the satellite transmissions. - * - * PRN is a binary signal with random noise-like properties. It is generated by mathematical algorithm or "code", - * and consists of repeated pattern of 1's and 0's. This binary code can be modulated on the GPS carrier - * waves using Binary Shift-Key (BSK) modulation. The C/A-Code and the P-Code are examples of PRN codes. - * Each satellite transmits a unique C/A-Code and P-Code sequence (on the same L1 and L2 frequencies), - * and hence a satellite may be identified according to its "PRN number", e.g. PRN2 or PRN14 are particular - * GPS satellites. - * - */ - public int getPRN() { - return PRN; - } - - /** - * Set PRN - * - * @param p - */ - public void setPRN(int p) { - PRN = p; - } - - /** - * How many degrees over the horizon the satellite is. This is a value between 0 and 90. - * 0 means it is by the horizon and 90 straight up. - * - * @return Elevation in degrees (0 to 90) - */ - public int getElevation() { - return elevation; - } - - /** - * Indicates if the GPS receiver is actively tracking this satellite and using it to fix the GPS location. - * @return true means this satellite is part of the GPS solution. false means it is probably obscured/unable to receive the signal. - */ - public boolean isTracked() { - return tracked; - } - - public void setTracked(boolean tracked) { - this.tracked = tracked; - } - - /** - * Set Elevation - * - * @param e - */ - public void setElevation(int e) { - elevation = e; - } - - /** - * Direction to the satellite in degrees. This is a value between 0 and 360. - * 0 is straight north, 90 is east, 180 is south and 270 is west. - * Any value in between is of course also valid. - * - * @return Azimuth in degrees, 0 to 360. - */ - - public int getAzimuth() { - return azimuth; - } - - /** - * Set Azimuth - * - * @param a - */ - public void setAzimuth(int a) { - azimuth = a; - } - - /** - * * Signal to Noise Ratio (SNR) for the signal from a satellite. This is a number between 0 and 99. - * Where 99 is perfect and 0 means the satellite is not available. A typical good value is 40. - * And a GPS typically starts using a satellite when its SNR value is higher than 25. - * - * @return SNR value between 0 and 99. - */ - - public int getSignalNoiseRatio() { - return SNR; - } - - /** - * Set SNR - * - * @param s - */ - public void setSignalNoiseRatio(int s) { - SNR = s; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/SimpleGPS.java b/ev3classes/src/main/java/lejos/hardware/gps/SimpleGPS.java deleted file mode 100644 index 3118c06..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/SimpleGPS.java +++ /dev/null @@ -1,381 +0,0 @@ -package lejos.hardware.gps; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.NoSuchElementException; - -/** - * This class manages data received from a GPS Device. - * SimpleGPS Class manages the following NMEA Sentences - * which supply location, heading, and speed data: - * - *

  • GPGGA (location data) - *
  • GPVTG (heading and speed data) - *
  • GPGSA (accuracy information) - * - *

    This class is primarily for use by the javax.microedition.location package. The preferred - * class to use for obtaining GPS data is the GPS class.

    - * - * @author BB - * @author Juan Antonio Breña Moral - * - */ -public class SimpleGPS extends Thread { - - - private InputStream in; - - //Classes which manages GGA, VTG, GSA Sentences - protected GGASentence ggaSentence; - protected VTGSentence vtgSentence; - protected GSASentence gsaSentence; - - // Security - private boolean close = false; - - // Listener-notifier - static private ArrayList listeners = new ArrayList(); - - - /** - * The constructor. It needs an InputStream - * - * @param in An input stream from the GPS receiver - */ - public SimpleGPS(InputStream in) { - this.in = new BufferedInputStream(in, 128); - - ggaSentence = new GGASentence(); - vtgSentence = new VTGSentence(); - gsaSentence = new GSASentence(); - - this.setDaemon(true); // Must be set before thread starts - this.start(); - } - - - /** - * Get Latitude - * - * @return the latitude - */ - public double getLatitude() { - return ggaSentence.getLatitude(); - } - - - /** - * Get Latitude Direction - * - * @return the latitude direction - */ - public char getLatitudeDirection(){ - return ggaSentence.getLatitudeDirection(); - } - - - /** - * Get Longitude - * - * @return the longitude - */ - public double getLongitude() { - return ggaSentence.getLongitude(); - } - - /** - * Get Longitude Direction - * - * @return the longitude direction - */ - public char getLongitudeDirection(){ - return ggaSentence.getLongitudeDirection(); - } - - - /** - * The altitude above mean sea level - * - * @return Meters above sea level e.g. 545.4 - */ - public float getAltitude(){ - return ggaSentence.getAltitude(); - } - - /** - * Returns the number of satellites being tracked to - * determine the coordinates. - * @return Number of satellites e.g. 8 - */ - public int getSatellitesTracked(){ - return ggaSentence.getSatellitesTracked(); - } - - /** - * Fix quality: - *
  • 0 = invalid - *
  • 1 = GPS fix (SPS) - *
  • 2 = DGPS fix - *
  • 3 = PPS fix - *
  • 4 = Real Time Kinematic - *
  • 5 = Float RTK - *
  • 6 = estimated (dead reckoning) (2.3 feature) - *
  • 7 = Manual input mode - *
  • 8 = Simulation mode - * - * @return the fix quality - */ - public int getFixMode(){ - return ggaSentence.getFixQuality(); - } - - /** - * Get the last time stamp from the satellite for GGA sentence. - * - * @return Time as a UTC integer. 123459 = 12:34:59 UTC - */ - public int getTimeStamp() { - return ggaSentence.getTime(); - } - - /** - * Get speed in kilometers per hour - * - * @return the speed in kilometers per hour - */ - public float getSpeed() { - return vtgSentence.getSpeed(); - } - - /** - * Get the course heading of the GPS unit. - * @return course (0.0 to 360.0) - */ - public float getCourse() { - return vtgSentence.getTrueCourse(); - } - - /** - * Selection type of 2D or 3D fix - *
  • 'M' = manual - *
  • 'A' = automatic - * @return selection type - either 'A' or 'M' - */ - public String getSelectionType(){ - return gsaSentence.getMode(); - } - - /** - * 3D fix - values include: - *
  • 1 = no fix - *
  • 2 = 2D fix - *
  • 3 = 3D fix - * - * @return fix type (1 to 3) - */ - public int getFixType(){ - return gsaSentence.getModeValue(); - } - - /** - * Get an Array of Pseudo-Random Noise codes (PRN). You can look up a list of GPS satellites by - * this number at: http://en.wikipedia.org/wiki/List_of_GPS_satellite_launches - * Note: This number might be similar or identical to SVN. - * - * @return array of PRNs - */ - public int[] getPRN(){ - return gsaSentence.getPRN(); - } - - /** - * Get the 3D Position Dilution of Precision (PDOP). When visible GPS satellites are close - * together in the sky, the geometry is said to be weak and the DOP value is high; when far - * apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents - * a better GPS positional accuracy due to the wider angular separation between the - * satellites used to calculate a GPS unit's position. Other factors that can increase - * the effective DOP are obstructions such as nearby mountains or buildings. - * - * @return The PDOP (PDOP * 6 meters = the error to expect in meters) -1 means PDOP is unavailable from the GPS. - */ - public float getPDOP(){ - return gsaSentence.getPDOP(); - } - - /** - * Get the Horizontal Dilution of Precision (HDOP). When visible GPS satellites are close - * together in the sky, the geometry is said to be weak and the DOP value is high; when far - * apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents - * a better GPS positional accuracy due to the wider angular separation between the - * satellites used to calculate a GPS unit's position. Other factors that can increase - * the effective DOP are obstructions such as nearby mountains or buildings. - * - * @return the HDOP (HDOP * 6 meters = the error to expect in meters) -1 means HDOP is unavailable from the GPS. - */ - public float getHDOP(){ - return gsaSentence.getHDOP(); - } - - /** - * Get the Vertical Dilution of Precision (VDOP). When visible GPS satellites are close - * together in the sky, the geometry is said to be weak and the DOP value is high; when far - * apart, the geometry is strong and the DOP value is low. Thus a low DOP value represents - * a better GPS positional accuracy due to the wider angular separation between the - * satellites used to calculate a GPS unit's position. Other factors that can increase - * the effective DOP are obstructions such as nearby mountains or buildings. - * - * @return the VDOP (VDOP * 6 meters = the error to expect in meters) -1 means VDOP is unavailable from the GPS. - */ - public float getVDOP(){ - return gsaSentence.getVDOP(); - } - - /** - * Method used to close connection. There is no real need to call this method. - * Included in case programmer wants absolutely clean exit. - */ - public void close() throws IOException { - this.close = true; - in.close(); - } - - /* - * EVENTS SECTION - * - */ - - protected static synchronized void notifyListeners(NMEASentence sen){ - /* TODO: Problem is ggaSentence is a reused object in this API. - * Should really pass a copy of the NMEASentence to notify (and the copy - * must have all the appropriate GGA data, not just NMEA). However, check - * if there are any listeners before making unnecessary copy. */ - - for(int i=0; i= 0) { - currentSentence.append((char)c); - c = in.read(); - - // trailing CR/LF marks EOL - if (c == '\n' || c == '\r') - break; - } - } catch (IOException e) { - //TODO handle errors - } - return currentSentence.toString(); - } - - /** - * Internal helper method to aid in the subclass architecture. Overwritten by subclass. - * @param header - * @param s - */ - protected void sentenceChooser(String header, String s) { - if (header.equals(GGASentence.HEADER)){ - this.ggaSentence.parse(s); - notifyListeners(this.ggaSentence); - }else if (header.equals(VTGSentence.HEADER)){ - this.vtgSentence.parse(s); - notifyListeners(this.vtgSentence); - }else if (header.equals(GSASentence.HEADER)){ - gsaSentence.parse(s); - notifyListeners(this.gsaSentence); - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/gps/VTGSentence.java b/ev3classes/src/main/java/lejos/hardware/gps/VTGSentence.java deleted file mode 100644 index c656f94..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/VTGSentence.java +++ /dev/null @@ -1,98 +0,0 @@ -package lejos.hardware.gps; - -import java.util.NoSuchElementException; - -/** - * VTGSentence is a Class designed to manage VTG Sentences from a NMEA GPS Receiver - * - * $GPVTG - * - * Track Made Good and Ground Speed. - * - * eg1. $GPVTG,360.0,T,348.7,M,000.0,N,000.0,K*43 - * eg2. $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*41 - * - * 054.7,T True course made good over ground, degrees - * 034.4,M Magnetic course made good over ground, degrees - * 005.5,N Ground speed, N=Knots - * 010.2,K Ground speed, K=Kilometers per hour - * - * eg3. for NMEA 0183 version 3.00 active the Mode indicator field - * is added at the end - * $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K,A*53 - * A Mode indicator (A=Autonomous, D=Differential, - * E=Estimated, N=Data not valid) - * - * @author Juan Antonio Brenha Moral - * - */ -public class VTGSentence extends NMEASentence{ - - //RMC Sentence - private String nmeaHeader = ""; - private final float KNOT = 1.852f; - private float speed = 0f; - private float trueCourse = 0f; - private float magneticCourse = 0f; - - //Header - public static final String HEADER = "$GPVTG"; - - /** - * Returns the NMEA header for this sentence. - */ - @Override - public String getHeader() { - return HEADER; - } - - /** - * Get true course, in degrees. - * - * @return the true course in degrees 0.0 to 360.0 - */ - public float getTrueCourse(){ - return trueCourse; - } - - /** - * Get Speed in Kilometers - * - * @return the speed - */ - public float getSpeed(){ - return speed; - } - - /** - * Parse a RMC Sentence - * - * $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K,A*53 - */ - public void parse(String sentence) { - - String[] parts = sentence.split(","); - - try{ - - //Processing VTG data - - nmeaHeader = parts[0];//$GPVTG - - if (parts[7].length() == 0){ - speed = 0; - } else { - speed = Float.parseFloat(parts[7]); - } - - //System.out.println(speed); - - } catch(NoSuchElementException e) { - //System.err.println("VTGSentence: NoSuchElementException"); - } catch(NumberFormatException e) { - //System.err.println("VTGSentence: NumberFormatException"); - } catch(Exception e){ - //System.err.println("VTGSentence: Exception"); - } - }//End Parse -}//End Class diff --git a/ev3classes/src/main/java/lejos/hardware/gps/package-info.java b/ev3classes/src/main/java/lejos/hardware/gps/package-info.java deleted file mode 100644 index e657567..0000000 --- a/ev3classes/src/main/java/lejos/hardware/gps/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * The lejos.hardware.gps package provides GPS parsing. In most cases you probably - * want to use the package javax.microedition.location, which is the standard - * Java API for obtaining GPS data. That package is built on top of the classes in this - * package.

    - * Additionally, this package offers more data, such as satellite information. - */ -package lejos.hardware.gps; diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/CommonLCD.java b/ev3classes/src/main/java/lejos/hardware/lcd/CommonLCD.java deleted file mode 100644 index 9895b84..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/CommonLCD.java +++ /dev/null @@ -1,120 +0,0 @@ -package lejos.hardware.lcd; - -public interface CommonLCD { - - /** - * Common raster operations for use with bitBlt - */ - public static final int ROP_CLEAR = 0x00000000; - public static final int ROP_AND = 0xff000000; - public static final int ROP_ANDREVERSE = 0xff00ff00; - public static final int ROP_COPY = 0x0000ff00; - public static final int ROP_ANDINVERTED = 0xffff0000; - public static final int ROP_NOOP = 0x00ff0000; - public static final int ROP_XOR = 0x00ffff00; - public static final int ROP_OR = 0xffffff00; - public static final int ROP_NOR = 0xffffffff; - public static final int ROP_EQUIV = 0x00ffffff; - public static final int ROP_INVERT = 0x00ff00ff; - public static final int ROP_ORREVERSE = 0xffff00ff; - public static final int ROP_COPYINVERTED = 0x0000ffff; - public static final int ROP_ORINVERTED = 0xff00ffff; - public static final int ROP_NAND = 0xff0000ff; - public static final int ROP_SET = 0x000000ff; - - /** - * Refresh the display. If auto refresh is off, this method will wait until - * the display refresh has completed. If auto refresh is on it will return - * immediately. - */ - public void refresh(); - - /** - * Clear the display. - */ - public void clear(); - - /** - * Return the width of the associated drawing surface. - *
    Note: This is a non standard method. - * @return width of the surface - */ - public int getWidth(); - - /** - * Return the height of the associated drawing surface. - *
    Note: This is a non standard method. - * @return height of the surface. - */ - public int getHeight(); - - /** - * Provide access to the LCD display frame buffer. - * @return byte array that is the frame buffer. - */ - public byte[] getDisplay(); - - /** - * Get access to hardware LCD display. - * @return byte array that is the frame buffer - */ - public byte[] getHWDisplay(); - - /** - * Set the LCD contrast. - * @param contrast 0 blank 0x60 full on - */ - public void setContrast(int contrast); - - /** - * Standard two input BitBlt function with the LCD display as the - * destination. Supports standard raster ops and - * overlapping images. Images are held in native leJOS/Lego format. - * @param src byte array containing the source image - * @param sw Width of the source image - * @param sh Height of the source image - * @param sx X position to start the copy from - * @param sy Y Position to start the copy from - * @param dx X destination - * @param dy Y destination - * @param w width of the area to copy - * @param h height of the area to copy - * @param rop raster operation. - */ - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, int dy, int w, int h, int rop); - - /** - * Standard two input BitBlt function. Supports standard raster ops and - * overlapping images. Images are held in native leJOS/Lego format. - * @param src byte array containing the source image - * @param sw Width of the source image - * @param sh Height of the source image - * @param sx X position to start the copy from - * @param sy Y Position to start the copy from - * @param dst byte array containing the destination image - * @param dw Width of the destination image - * @param dh Height of the destination image - * @param dx X destination - * @param dy Y destination - * @param w width of the area to copy - * @param h height of the area to copy - * @param rop raster operation. - */ - 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); - - /** - * Turn on/off the automatic refresh of the LCD display. At system startup - * auto refresh is on. - * @param on true to enable, false to disable - */ - public void setAutoRefresh(boolean on); - - /** - * Set the period used to perform automatic refreshing of the display. - * A period of 0 disables the refresh. - * @param period time in ms - * @return the previous refresh period. - */ - public int setAutoRefreshPeriod(int period); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/Font.java b/ev3classes/src/main/java/lejos/hardware/lcd/Font.java deleted file mode 100644 index ea6e90d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/Font.java +++ /dev/null @@ -1,2304 +0,0 @@ -package lejos.hardware.lcd; - -import java.io.Serializable; - -/** - * Provides access to fonts for use with the display or images. The actual font - * data is held as a series of glyphs with all inter character spacing removed. - * The format of the bitmap is in standard leJOS format (so aligned for use on - * NXT LCD display). There is one bit per pixel. The pixels are packed into bytes - * with each byte spanning 8 scan lines. The least significant bit of each byte - * is the pixel for the top most scan line, the most significant bit is the - * 8th scan line. Values of 1 represent black. 0 white. - * @author Andy - */ -public class Font implements Serializable -{ - private static final long serialVersionUID = 1550412879619616244L; - public final int width; - public final int height; - public final int glyphWidth; - public final int glyphCount; - public final int firstChar; - public final int base; - public final byte[] glyphs; - public final static int SIZE_SMALL = 8; - public final static int SIZE_MEDIUM = 0; - public final static int SIZE_LARGE = 16; - private static Font small; - private static Font large; - private static Font medium; - - // The folowing classes contain the glyph bitmaps for the additonal fonts. - // They are wrapped inside of classes to allow the linker to eliminate the - // array initialization if the font is not used. - /** - * Small system font (4x6) - */ - static class TinyFont extends Font - { - - /** - * - */ - private static final long serialVersionUID = 1938158022862726819L; - - TinyFont() - { - super( - new byte[] {(byte) 0x40, (byte) 0xaa, (byte) 0x24, (byte) 0x64, (byte) 0x24, - (byte) 0x0a, (byte) 0x00, (byte) 0x80, (byte) 0x4c, (byte) 0x66, - (byte) 0xe8, (byte) 0xe4, (byte) 0x44, (byte) 0x00, (byte) 0x08, - (byte) 0x62, (byte) 0x4e, (byte) 0xc6, (byte) 0xe6, (byte) 0xce, - (byte) 0xea, (byte) 0xa8, (byte) 0xa2, (byte) 0x4a, (byte) 0x46, - (byte) 0xc6, (byte) 0xae, (byte) 0xaa, (byte) 0xaa, (byte) 0x6e, - (byte) 0x62, (byte) 0x04, (byte) 0x06, (byte) 0x02, (byte) 0x08, - (byte) 0x08, (byte) 0x42, (byte) 0x24, (byte) 0x04, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x64, (byte) 0x0a, (byte) 0x40, (byte) 0xea, - (byte) 0x8c, (byte) 0x2a, (byte) 0x42, (byte) 0x44, (byte) 0x00, - (byte) 0x80, (byte) 0x6a, (byte) 0x88, (byte) 0x2a, (byte) 0x82, - (byte) 0xaa, (byte) 0x00, (byte) 0x04, (byte) 0x84, (byte) 0xaa, - (byte) 0x2a, (byte) 0x2a, (byte) 0x22, (byte) 0x4a, (byte) 0xa8, - (byte) 0xe2, (byte) 0xae, (byte) 0xaa, (byte) 0x2a, (byte) 0xa4, - (byte) 0xaa, (byte) 0xaa, (byte) 0x28, (byte) 0x42, (byte) 0x0a, - (byte) 0x04, (byte) 0x02, (byte) 0x08, (byte) 0x04, (byte) 0x02, - (byte) 0x20, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x44, - (byte) 0x05, (byte) 0x40, (byte) 0xa0, (byte) 0x46, (byte) 0x0c, - (byte) 0x42, (byte) 0xee, (byte) 0xe0, (byte) 0x40, (byte) 0x4a, - (byte) 0x44, (byte) 0x6e, (byte) 0xc6, (byte) 0xc4, (byte) 0x44, - (byte) 0xe2, (byte) 0x48, (byte) 0xea, (byte) 0x26, (byte) 0x6a, - (byte) 0xa6, (byte) 0x4e, (byte) 0x68, (byte) 0xe2, (byte) 0xaa, - (byte) 0xa6, (byte) 0xe6, (byte) 0xa4, (byte) 0xea, (byte) 0x44, - (byte) 0x24, (byte) 0x44, (byte) 0x00, (byte) 0xc0, (byte) 0xc6, - (byte) 0xec, (byte) 0xee, (byte) 0x46, (byte) 0xa4, (byte) 0xe4, - (byte) 0x46, (byte) 0xc6, (byte) 0xc6, (byte) 0xae, (byte) 0xaa, - (byte) 0xaa, (byte) 0x66, (byte) 0xc4, (byte) 0x00, (byte) 0x00, - (byte) 0xe0, (byte) 0x2c, (byte) 0x0a, (byte) 0x42, (byte) 0x44, - (byte) 0x00, (byte) 0x20, (byte) 0x4a, (byte) 0x82, (byte) 0x88, - (byte) 0x4a, (byte) 0x8a, (byte) 0x00, (byte) 0x04, (byte) 0x04, - (byte) 0xa2, (byte) 0x2a, (byte) 0x2a, (byte) 0xa2, (byte) 0x4a, - (byte) 0xaa, (byte) 0xa2, (byte) 0xaa, (byte) 0xe2, (byte) 0x8a, - (byte) 0xa4, (byte) 0xea, (byte) 0x4a, (byte) 0x22, (byte) 0x48, - (byte) 0x00, (byte) 0xa0, (byte) 0x2a, (byte) 0x6a, (byte) 0xa4, - (byte) 0x4a, (byte) 0x64, (byte) 0xe4, (byte) 0xaa, (byte) 0xaa, - (byte) 0x42, (byte) 0xa4, (byte) 0xea, (byte) 0xa4, (byte) 0x44, - (byte) 0x44, (byte) 0x00, (byte) 0x40, (byte) 0xa0, (byte) 0x86, - (byte) 0x0e, (byte) 0x24, (byte) 0x0a, (byte) 0x06, (byte) 0x24, - (byte) 0xe6, (byte) 0x6e, (byte) 0x68, (byte) 0x44, (byte) 0x44, - (byte) 0x64, (byte) 0xe8, (byte) 0x42, (byte) 0xae, (byte) 0xc6, - (byte) 0xe6, (byte) 0xc2, (byte) 0xea, (byte) 0xa4, (byte) 0xae, - (byte) 0x4a, (byte) 0xc2, (byte) 0x6a, (byte) 0xe4, (byte) 0xa4, - (byte) 0x4a, (byte) 0x6e, (byte) 0x68, (byte) 0x00, (byte) 0xe0, - (byte) 0xc6, (byte) 0xcc, (byte) 0x84, (byte) 0x4a, (byte) 0xa4, - (byte) 0xa4, (byte) 0x4a, (byte) 0xc6, (byte) 0x62, (byte) 0xec, - (byte) 0xe4, (byte) 0x4a, (byte) 0xcc, (byte) 0x64, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xe0, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x82, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x20, - (byte) 0x00, (byte) 0x00, (byte) 0x00, }, - 4, 6, 5, 4, 96, 32); - } - } - - /** - * Small font 6x8 - * This is the same size as the system font, so we use that - */ - static class SmallFont extends Font - { - - /** - * - */ - private static final long serialVersionUID = -7778038990105368925L; - - SmallFont() - { - super( - new byte[] {(byte) 0x00, (byte) 0x62, (byte) 0x03, (byte) 0x84, (byte) 0x49, - (byte) 0x30, (byte) 0x08, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x1c, (byte) 0xc2, (byte) 0x71, - (byte) 0x90, (byte) 0x8f, (byte) 0xf9, (byte) 0x1c, (byte) 0x07, - (byte) 0x00, (byte) 0x10, (byte) 0x40, (byte) 0x70, (byte) 0x1c, - (byte) 0xe7, (byte) 0x71, (byte) 0x9e, (byte) 0xef, (byte) 0x73, - (byte) 0x22, (byte) 0x07, (byte) 0x8a, (byte) 0x82, (byte) 0x28, - (byte) 0x72, (byte) 0x1e, (byte) 0xe7, (byte) 0x71, (byte) 0xbe, - (byte) 0x28, (byte) 0x8a, (byte) 0xa2, (byte) 0xe8, (byte) 0x71, - (byte) 0x00, (byte) 0x87, (byte) 0x00, (byte) 0x0c, (byte) 0x20, - (byte) 0x00, (byte) 0x20, (byte) 0x80, (byte) 0x01, (byte) 0x02, - (byte) 0x02, (byte) 0x09, (byte) 0x08, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x08, - (byte) 0x43, (byte) 0x21, (byte) 0x00, (byte) 0x67, (byte) 0x53, - (byte) 0x9c, (byte) 0xa9, (byte) 0x30, (byte) 0x04, (byte) 0x42, - (byte) 0x21, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x22, - (byte) 0x23, (byte) 0x8a, (byte) 0x98, (byte) 0x40, (byte) 0x80, - (byte) 0xa2, (byte) 0x08, (byte) 0x00, (byte) 0x08, (byte) 0x80, - (byte) 0x88, (byte) 0xa2, (byte) 0x28, (byte) 0x8a, (byte) 0xa2, - (byte) 0x20, (byte) 0x88, (byte) 0x22, (byte) 0x02, (byte) 0x4a, - (byte) 0x82, (byte) 0x6d, (byte) 0x8a, (byte) 0xa2, (byte) 0x28, - (byte) 0x8a, (byte) 0x88, (byte) 0x28, (byte) 0x8a, (byte) 0xa2, - (byte) 0x08, (byte) 0x11, (byte) 0x02, (byte) 0x44, (byte) 0x01, - (byte) 0x0c, (byte) 0x20, (byte) 0x00, (byte) 0x20, (byte) 0x40, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x08, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x10, (byte) 0x08, (byte) 0xa4, (byte) 0x70, (byte) 0x00, - (byte) 0x27, (byte) 0xf9, (byte) 0x02, (byte) 0xa4, (byte) 0x10, - (byte) 0x04, (byte) 0xc2, (byte) 0x21, (byte) 0x00, (byte) 0x00, - (byte) 0x40, (byte) 0x32, (byte) 0x02, (byte) 0x82, (byte) 0x94, - (byte) 0x20, (byte) 0x40, (byte) 0xa2, (byte) 0xc8, (byte) 0x30, - (byte) 0x84, (byte) 0x0f, (byte) 0x81, (byte) 0xba, (byte) 0x28, - (byte) 0x0a, (byte) 0xa2, (byte) 0x20, (byte) 0x08, (byte) 0x22, - (byte) 0x02, (byte) 0x2a, (byte) 0x82, (byte) 0xaa, (byte) 0x8a, - (byte) 0xa2, (byte) 0x28, (byte) 0x0a, (byte) 0x88, (byte) 0x28, - (byte) 0xaa, (byte) 0x94, (byte) 0x88, (byte) 0x10, (byte) 0x04, - (byte) 0x24, (byte) 0x02, (byte) 0x08, (byte) 0xe7, (byte) 0x71, - (byte) 0x3c, (byte) 0x47, (byte) 0xf0, (byte) 0x0e, (byte) 0x82, - (byte) 0x49, (byte) 0x88, (byte) 0xe5, (byte) 0x70, (byte) 0x1e, - (byte) 0xaf, (byte) 0x71, (byte) 0x9e, (byte) 0x24, (byte) 0x8a, - (byte) 0x92, (byte) 0xe4, (byte) 0x11, (byte) 0x08, (byte) 0x04, - (byte) 0xd8, (byte) 0x00, (byte) 0x02, (byte) 0x50, (byte) 0x0c, - (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xe2, (byte) 0xfb, - (byte) 0x80, (byte) 0x0f, (byte) 0x20, (byte) 0x2a, (byte) 0x82, - (byte) 0x71, (byte) 0x92, (byte) 0xe7, (byte) 0x21, (byte) 0x1c, - (byte) 0xcf, (byte) 0x30, (byte) 0x02, (byte) 0x00, (byte) 0x62, - (byte) 0xaa, (byte) 0xe8, (byte) 0x09, (byte) 0xa2, (byte) 0xe7, - (byte) 0xe9, (byte) 0x3e, (byte) 0x02, (byte) 0x1a, (byte) 0x82, - (byte) 0x28, (byte) 0x8b, (byte) 0x9e, (byte) 0xe8, (byte) 0x71, - (byte) 0x88, (byte) 0x28, (byte) 0xaa, (byte) 0x08, (byte) 0x45, - (byte) 0x10, (byte) 0x08, (byte) 0x04, (byte) 0x00, (byte) 0x00, - (byte) 0x28, (byte) 0x8a, (byte) 0xa2, (byte) 0xe8, (byte) 0x89, - (byte) 0x12, (byte) 0x02, (byte) 0x29, (byte) 0x88, (byte) 0x2a, - (byte) 0x89, (byte) 0xa2, (byte) 0x48, (byte) 0x0a, (byte) 0x84, - (byte) 0x24, (byte) 0x8a, (byte) 0x92, (byte) 0x04, (byte) 0x19, - (byte) 0x00, (byte) 0x0c, (byte) 0x88, (byte) 0x00, (byte) 0x02, - (byte) 0x50, (byte) 0x10, (byte) 0xa1, (byte) 0x02, (byte) 0x04, - (byte) 0xc2, (byte) 0x21, (byte) 0x00, (byte) 0x00, (byte) 0x10, - (byte) 0x26, (byte) 0x42, (byte) 0x80, (byte) 0x3e, (byte) 0x28, - (byte) 0x12, (byte) 0x22, (byte) 0x08, (byte) 0x00, (byte) 0x04, - (byte) 0x00, (byte) 0x21, (byte) 0xba, (byte) 0x2f, (byte) 0x0a, - (byte) 0xa2, (byte) 0x20, (byte) 0x88, (byte) 0x22, (byte) 0x22, - (byte) 0x2a, (byte) 0x82, (byte) 0x28, (byte) 0x8a, (byte) 0x82, - (byte) 0x2a, (byte) 0x81, (byte) 0x88, (byte) 0x28, (byte) 0xaa, - (byte) 0x14, (byte) 0x22, (byte) 0x10, (byte) 0x10, (byte) 0x04, - (byte) 0x00, (byte) 0x00, (byte) 0x2f, (byte) 0x0a, (byte) 0xa2, - (byte) 0x47, (byte) 0x88, (byte) 0x12, (byte) 0x02, (byte) 0x19, - (byte) 0x88, (byte) 0x2a, (byte) 0x89, (byte) 0xa2, (byte) 0x48, - (byte) 0x70, (byte) 0x84, (byte) 0x24, (byte) 0xaa, (byte) 0x8c, - (byte) 0xc4, (byte) 0x10, (byte) 0x08, (byte) 0x04, (byte) 0x88, - (byte) 0x00, (byte) 0x00, (byte) 0xf8, (byte) 0x8e, (byte) 0x2c, - (byte) 0x01, (byte) 0x04, (byte) 0x42, (byte) 0x21, (byte) 0x0c, - (byte) 0xc0, (byte) 0x08, (byte) 0x22, (byte) 0x22, (byte) 0x88, - (byte) 0x90, (byte) 0x28, (byte) 0x12, (byte) 0x22, (byte) 0xc4, - (byte) 0x30, (byte) 0x88, (byte) 0x8f, (byte) 0x00, (byte) 0x82, - (byte) 0x28, (byte) 0x8a, (byte) 0xa2, (byte) 0x20, (byte) 0x88, - (byte) 0x22, (byte) 0x22, (byte) 0x4a, (byte) 0x82, (byte) 0x28, - (byte) 0x8a, (byte) 0x82, (byte) 0x24, (byte) 0x8a, (byte) 0x88, - (byte) 0x48, (byte) 0xa9, (byte) 0x22, (byte) 0x22, (byte) 0x10, - (byte) 0x20, (byte) 0x04, (byte) 0x00, (byte) 0x80, (byte) 0x28, - (byte) 0x8a, (byte) 0xa2, (byte) 0x40, (byte) 0xf0, (byte) 0x12, - (byte) 0x02, (byte) 0x29, (byte) 0x88, (byte) 0x28, (byte) 0x89, - (byte) 0xa2, (byte) 0x48, (byte) 0x80, (byte) 0x94, (byte) 0x46, - (byte) 0xf9, (byte) 0x12, (byte) 0x27, (byte) 0x10, (byte) 0x08, - (byte) 0x04, (byte) 0xf8, (byte) 0x00, (byte) 0x02, (byte) 0x50, - (byte) 0x88, (byte) 0xcc, (byte) 0x02, (byte) 0x08, (byte) 0x01, - (byte) 0x00, (byte) 0x0c, (byte) 0xc0, (byte) 0x00, (byte) 0x1c, - (byte) 0xe7, (byte) 0x73, (byte) 0x10, (byte) 0xc7, (byte) 0x11, - (byte) 0x1c, (byte) 0xc3, (byte) 0x30, (byte) 0x10, (byte) 0x40, - (byte) 0x20, (byte) 0x9c, (byte) 0xe8, (byte) 0x71, (byte) 0x9e, - (byte) 0x2f, (byte) 0xf0, (byte) 0x22, (byte) 0xc7, (byte) 0x89, - (byte) 0xbe, (byte) 0x28, (byte) 0x72, (byte) 0x02, (byte) 0x2b, - (byte) 0x72, (byte) 0x08, (byte) 0x87, (byte) 0x50, (byte) 0x22, - (byte) 0xe2, (byte) 0x71, (byte) 0x00, (byte) 0x07, (byte) 0x00, - (byte) 0x00, (byte) 0xef, (byte) 0x71, (byte) 0x3c, (byte) 0x47, - (byte) 0x80, (byte) 0x12, (byte) 0x26, (byte) 0x49, (byte) 0x98, - (byte) 0x28, (byte) 0x71, (byte) 0x1e, (byte) 0xef, (byte) 0x70, - (byte) 0x08, (byte) 0x85, (byte) 0x50, (byte) 0x12, (byte) 0xe2, - (byte) 0x61, (byte) 0x08, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x10, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xfc, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x70, (byte) 0x00, (byte) 0xc0, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, - (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, }, - 6, 8, 7, 6, 96, 32); - } - } - - /** - * Medium font 10x16 - */ - static class MediumFont extends Font - { - - /** - * - */ - private static final long serialVersionUID = -1916404682626635141L; - - MediumFont() - { - super ( - new byte[] {(byte) 0x00, (byte) 0xc0, (byte) 0xc0, (byte) 0x0c, (byte) 0x00, - (byte) 0x30, (byte) 0x10, (byte) 0xc6, (byte) 0x03, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60, - (byte) 0x78, (byte) 0xc0, (byte) 0x80, (byte) 0x07, (byte) 0x1e, - (byte) 0x30, (byte) 0xf8, (byte) 0x07, (byte) 0x9e, (byte) 0x7f, - (byte) 0x78, (byte) 0xe0, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3f, - (byte) 0xf8, (byte) 0xe0, (byte) 0xe1, (byte) 0x07, (byte) 0x1e, - (byte) 0x7e, (byte) 0xf8, (byte) 0xe7, (byte) 0x1f, (byte) 0x1e, - (byte) 0x86, (byte) 0xf9, (byte) 0x07, (byte) 0x98, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x18, (byte) 0x1e, - (byte) 0x7e, (byte) 0xe0, (byte) 0xe1, (byte) 0x07, (byte) 0x1e, - (byte) 0xfe, (byte) 0x19, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0xe6, (byte) 0x1f, (byte) 0x1e, - (byte) 0x06, (byte) 0xe0, (byte) 0x01, (byte) 0x03, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x0f, (byte) 0x00, - (byte) 0x06, (byte) 0xc0, (byte) 0x00, (byte) 0x86, (byte) 0x01, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x38, - (byte) 0x30, (byte) 0x70, (byte) 0x80, (byte) 0x19, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0xc1, (byte) 0x0c, (byte) 0x33, - (byte) 0x30, (byte) 0x38, (byte) 0x62, (byte) 0x06, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x60, - (byte) 0xcc, (byte) 0xe0, (byte) 0xc0, (byte) 0x0c, (byte) 0x33, - (byte) 0x30, (byte) 0x18, (byte) 0x00, (byte) 0x03, (byte) 0x60, - (byte) 0xcc, (byte) 0x30, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x73, - (byte) 0x8c, (byte) 0x31, (byte) 0x63, (byte) 0x0c, (byte) 0x33, - (byte) 0xc6, (byte) 0x18, (byte) 0x60, (byte) 0x00, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x18, (byte) 0x33, - (byte) 0xc6, (byte) 0x30, (byte) 0x63, (byte) 0x0c, (byte) 0x33, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x18, (byte) 0x06, - (byte) 0x06, (byte) 0x80, (byte) 0x81, (byte) 0x0f, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x80, (byte) 0x19, (byte) 0x00, - (byte) 0x06, (byte) 0xc0, (byte) 0x00, (byte) 0x86, (byte) 0x01, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x60, (byte) 0x06, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0xc1, (byte) 0x0c, (byte) 0x33, - (byte) 0xfc, (byte) 0x28, (byte) 0x23, (byte) 0x04, (byte) 0x08, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x30, - (byte) 0x86, (byte) 0xf9, (byte) 0x60, (byte) 0x98, (byte) 0x61, - (byte) 0x18, (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x60, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x00, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x06, (byte) 0x1b, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0xc6, (byte) 0x18, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x31, - (byte) 0x06, (byte) 0x18, (byte) 0xe6, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x18, (byte) 0x06, - (byte) 0x0c, (byte) 0x80, (byte) 0xe1, (byte) 0x1c, (byte) 0x00, - (byte) 0x10, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x80, (byte) 0x01, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x01, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0x01, (byte) 0x00, (byte) 0x33, - (byte) 0xb6, (byte) 0x29, (byte) 0x21, (byte) 0x04, (byte) 0x04, - (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x30, - (byte) 0xc6, (byte) 0xc1, (byte) 0x60, (byte) 0x98, (byte) 0x61, - (byte) 0x18, (byte) 0x18, (byte) 0xc0, (byte) 0x00, (byte) 0x60, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x60, (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x60, - (byte) 0x06, (byte) 0x1b, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x39, - (byte) 0x06, (byte) 0x38, (byte) 0xe7, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x0c, (byte) 0x06, - (byte) 0x0c, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x20, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x80, (byte) 0x01, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x01, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0x01, (byte) 0x00, (byte) 0x33, - (byte) 0xb6, (byte) 0xb9, (byte) 0x61, (byte) 0x06, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x18, - (byte) 0xc6, (byte) 0xc1, (byte) 0x00, (byte) 0x18, (byte) 0x60, - (byte) 0x18, (byte) 0x18, (byte) 0xc0, (byte) 0x00, (byte) 0x30, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x80, (byte) 0x01, (byte) 0x70, - (byte) 0xe6, (byte) 0x1b, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x01, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x19, - (byte) 0x06, (byte) 0x38, (byte) 0xe7, (byte) 0x99, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0xcc, (byte) 0x18, (byte) 0x06, (byte) 0x0c, (byte) 0x06, - (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, - (byte) 0x80, (byte) 0x01, (byte) 0x80, (byte) 0x01, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x01, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0x01, (byte) 0x80, (byte) 0x7f, - (byte) 0x3e, (byte) 0x90, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0xc1, (byte) 0x0c, (byte) 0x0c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x18, - (byte) 0xa6, (byte) 0xc1, (byte) 0x00, (byte) 0x18, (byte) 0x60, - (byte) 0x0c, (byte) 0xf8, (byte) 0x61, (byte) 0x00, (byte) 0x30, - (byte) 0xcc, (byte) 0x18, (byte) 0x06, (byte) 0x03, (byte) 0x0c, - (byte) 0x18, (byte) 0xf8, (byte) 0x07, (byte) 0x03, (byte) 0x30, - (byte) 0x36, (byte) 0x1b, (byte) 0x66, (byte) 0x8c, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x01, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x0d, - (byte) 0x06, (byte) 0x38, (byte) 0x67, (byte) 0x99, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x98, (byte) 0x07, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0xcc, (byte) 0x18, (byte) 0x06, (byte) 0x06, (byte) 0x06, - (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xe0, (byte) 0x63, (byte) 0x07, (byte) 0x3e, - (byte) 0xb8, (byte) 0xe1, (byte) 0xe1, (byte) 0x0f, (byte) 0x6e, - (byte) 0x76, (byte) 0xf0, (byte) 0x80, (byte) 0x87, (byte) 0x61, - (byte) 0x30, (byte) 0x38, (byte) 0x63, (byte) 0x07, (byte) 0x1e, - (byte) 0x76, (byte) 0xe0, (byte) 0x66, (byte) 0x0e, (byte) 0x3f, - (byte) 0xfc, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0xe6, (byte) 0x1f, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0x38, (byte) 0xc0, (byte) 0x80, (byte) 0x01, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0x81, (byte) 0x07, (byte) 0x0c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0xa6, (byte) 0xc1, (byte) 0x00, (byte) 0x0c, (byte) 0x3e, - (byte) 0x0c, (byte) 0x00, (byte) 0xe3, (byte) 0x07, (byte) 0x30, - (byte) 0x78, (byte) 0x30, (byte) 0x06, (byte) 0x03, (byte) 0x0c, - (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x18, - (byte) 0x36, (byte) 0x1b, (byte) 0xe6, (byte) 0x87, (byte) 0x01, - (byte) 0x86, (byte) 0xf9, (byte) 0x63, (byte) 0x80, (byte) 0x01, - (byte) 0xfe, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x07, - (byte) 0x06, (byte) 0xf8, (byte) 0x67, (byte) 0x9b, (byte) 0x61, - (byte) 0xc6, (byte) 0x18, (byte) 0x66, (byte) 0x0c, (byte) 0x0f, - (byte) 0x30, (byte) 0x18, (byte) 0xc6, (byte) 0x8c, (byte) 0x6d, - (byte) 0x78, (byte) 0x30, (byte) 0x03, (byte) 0x03, (byte) 0x06, - (byte) 0x30, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x10, (byte) 0xe6, (byte) 0x0c, (byte) 0x63, - (byte) 0xcc, (byte) 0x31, (byte) 0x83, (byte) 0x01, (byte) 0x73, - (byte) 0xce, (byte) 0xc0, (byte) 0x00, (byte) 0x86, (byte) 0x31, - (byte) 0x30, (byte) 0xf8, (byte) 0xe7, (byte) 0x0c, (byte) 0x33, - (byte) 0xce, (byte) 0x10, (byte) 0xe7, (byte) 0x9f, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x6d, - (byte) 0x86, (byte) 0x19, (byte) 0x06, (byte) 0x18, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0x70, (byte) 0x40, (byte) 0xc0, (byte) 0x13, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0xe1, (byte) 0x9f, (byte) 0x7f, - (byte) 0x00, (byte) 0xf8, (byte) 0x07, (byte) 0x00, (byte) 0x0c, - (byte) 0x96, (byte) 0xc1, (byte) 0x00, (byte) 0x06, (byte) 0x60, - (byte) 0x6c, (byte) 0x00, (byte) 0x66, (byte) 0x0c, (byte) 0x18, - (byte) 0xcc, (byte) 0xe0, (byte) 0x07, (byte) 0x00, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x0c, (byte) 0x18, - (byte) 0x36, (byte) 0x1b, (byte) 0x66, (byte) 0x8c, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0xe0, (byte) 0x8f, (byte) 0x79, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x07, - (byte) 0x06, (byte) 0xd8, (byte) 0x66, (byte) 0x9a, (byte) 0x61, - (byte) 0x7e, (byte) 0x18, (byte) 0xe6, (byte) 0x07, (byte) 0x3c, - (byte) 0x30, (byte) 0x18, (byte) 0xc6, (byte) 0x8c, (byte) 0x6d, - (byte) 0x78, (byte) 0xf0, (byte) 0x83, (byte) 0x01, (byte) 0x06, - (byte) 0x30, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x86, (byte) 0x81, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x19, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0xe6, (byte) 0x80, (byte) 0x01, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x6d, - (byte) 0xcc, (byte) 0x18, (byte) 0x06, (byte) 0x0c, (byte) 0x06, - (byte) 0x30, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x80, (byte) 0x7f, - (byte) 0xf0, (byte) 0x61, (byte) 0x62, (byte) 0x1e, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0x81, (byte) 0x07, (byte) 0x0c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, - (byte) 0x96, (byte) 0xc1, (byte) 0x00, (byte) 0x03, (byte) 0x60, - (byte) 0x66, (byte) 0x00, (byte) 0x66, (byte) 0x18, (byte) 0x18, - (byte) 0x86, (byte) 0x01, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x0c, (byte) 0xf8, (byte) 0x07, (byte) 0x06, (byte) 0x0c, - (byte) 0xb6, (byte) 0xfb, (byte) 0x67, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x0d, - (byte) 0x06, (byte) 0xd8, (byte) 0x66, (byte) 0x9e, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x06, (byte) 0x78, - (byte) 0x30, (byte) 0x18, (byte) 0xc6, (byte) 0x8c, (byte) 0x6d, - (byte) 0xcc, (byte) 0xe0, (byte) 0x81, (byte) 0x01, (byte) 0x06, - (byte) 0x60, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x67, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x86, (byte) 0x81, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x0d, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x00, (byte) 0x07, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x6d, - (byte) 0xfc, (byte) 0x18, (byte) 0x06, (byte) 0x06, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0xb6, (byte) 0x21, (byte) 0x27, (byte) 0x0c, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0xc1, (byte) 0x0c, (byte) 0x0c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, - (byte) 0x8e, (byte) 0xc1, (byte) 0x80, (byte) 0x01, (byte) 0x60, - (byte) 0x66, (byte) 0x00, (byte) 0x66, (byte) 0x18, (byte) 0x18, - (byte) 0x86, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x18, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x0c, - (byte) 0x66, (byte) 0x1b, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x98, (byte) 0x19, - (byte) 0x06, (byte) 0xd8, (byte) 0x66, (byte) 0x9c, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x0c, (byte) 0x60, - (byte) 0x30, (byte) 0x18, (byte) 0x86, (byte) 0x04, (byte) 0x33, - (byte) 0xcc, (byte) 0xc0, (byte) 0xc0, (byte) 0x00, (byte) 0x06, - (byte) 0x60, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0xf9, (byte) 0x87, (byte) 0x81, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x07, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x6d, - (byte) 0x30, (byte) 0x18, (byte) 0x06, (byte) 0x03, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0xb6, (byte) 0x31, (byte) 0x25, (byte) 0x04, (byte) 0x00, - (byte) 0x18, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, - (byte) 0x8e, (byte) 0xc1, (byte) 0xc0, (byte) 0x80, (byte) 0x61, - (byte) 0x66, (byte) 0x18, (byte) 0x66, (byte) 0x18, (byte) 0x0c, - (byte) 0x86, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x80, (byte) 0x01, (byte) 0x00, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x60, (byte) 0x98, (byte) 0x39, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x9c, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x8c, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x86, (byte) 0x07, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0xc0, (byte) 0x00, (byte) 0x06, - (byte) 0xc0, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x80, (byte) 0x81, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x0f, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x00, (byte) 0x38, - (byte) 0x30, (byte) 0x18, (byte) 0xc6, (byte) 0x8c, (byte) 0x6d, - (byte) 0xfc, (byte) 0x30, (byte) 0x83, (byte) 0x01, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0xfc, (byte) 0x10, (byte) 0x25, (byte) 0x0c, (byte) 0x00, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, - (byte) 0x86, (byte) 0xc1, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0xfe, (byte) 0x19, (byte) 0x66, (byte) 0x18, (byte) 0x0c, - (byte) 0x86, (byte) 0x81, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x60, (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0xc6, (byte) 0x18, (byte) 0x60, (byte) 0x80, (byte) 0x61, - (byte) 0x86, (byte) 0xc1, (byte) 0x60, (byte) 0x98, (byte) 0x31, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x8c, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x86, (byte) 0x07, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0x60, (byte) 0x00, (byte) 0x06, - (byte) 0xc0, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0x66, (byte) 0x98, (byte) 0x01, - (byte) 0x86, (byte) 0x19, (byte) 0x80, (byte) 0x01, (byte) 0x73, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x19, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x98, (byte) 0x61, - (byte) 0x86, (byte) 0x19, (byte) 0x66, (byte) 0x00, (byte) 0x60, - (byte) 0x30, (byte) 0x18, (byte) 0x86, (byte) 0x04, (byte) 0x33, - (byte) 0xcc, (byte) 0x30, (byte) 0xc3, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x33, - (byte) 0x30, (byte) 0x18, (byte) 0x67, (byte) 0x1e, (byte) 0x00, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x83, (byte) 0x01, - (byte) 0xcc, (byte) 0xc0, (byte) 0x60, (byte) 0x00, (byte) 0x33, - (byte) 0x60, (byte) 0x30, (byte) 0xc3, (byte) 0x0c, (byte) 0x0c, - (byte) 0xcc, (byte) 0xc0, (byte) 0x00, (byte) 0x03, (byte) 0x0c, - (byte) 0xc0, (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x0c, - (byte) 0x0c, (byte) 0x1b, (byte) 0x66, (byte) 0x0c, (byte) 0x33, - (byte) 0xc6, (byte) 0x18, (byte) 0x60, (byte) 0x00, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0xc0, (byte) 0x8c, (byte) 0x61, - (byte) 0x06, (byte) 0x18, (byte) 0x66, (byte) 0x18, (byte) 0x33, - (byte) 0x06, (byte) 0x30, (byte) 0x63, (byte) 0x0c, (byte) 0x33, - (byte) 0x30, (byte) 0x30, (byte) 0x03, (byte) 0x03, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0x60, (byte) 0x00, (byte) 0x06, - (byte) 0x80, (byte) 0x81, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0xe7, (byte) 0x0c, (byte) 0x63, - (byte) 0xcc, (byte) 0x31, (byte) 0x86, (byte) 0x01, (byte) 0x6e, - (byte) 0x86, (byte) 0xc1, (byte) 0x00, (byte) 0x86, (byte) 0x31, - (byte) 0x30, (byte) 0xd8, (byte) 0x66, (byte) 0x18, (byte) 0x33, - (byte) 0xce, (byte) 0x10, (byte) 0x67, (byte) 0x80, (byte) 0x61, - (byte) 0x30, (byte) 0x18, (byte) 0x87, (byte) 0x07, (byte) 0x33, - (byte) 0x86, (byte) 0xe1, (byte) 0x61, (byte) 0x00, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x08, (byte) 0xc2, (byte) 0x13, (byte) 0x00, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x83, (byte) 0x01, - (byte) 0x78, (byte) 0xf8, (byte) 0xe7, (byte) 0x1f, (byte) 0x1e, - (byte) 0x60, (byte) 0xe0, (byte) 0x81, (byte) 0x07, (byte) 0x0c, - (byte) 0x78, (byte) 0x78, (byte) 0x00, (byte) 0x03, (byte) 0x0c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0c, - (byte) 0xf8, (byte) 0x19, (byte) 0xe6, (byte) 0x07, (byte) 0x1e, - (byte) 0x7e, (byte) 0xf8, (byte) 0x67, (byte) 0x00, (byte) 0x1e, - (byte) 0x86, (byte) 0xf9, (byte) 0x87, (byte) 0x87, (byte) 0x61, - (byte) 0xfe, (byte) 0x19, (byte) 0x66, (byte) 0x18, (byte) 0x1e, - (byte) 0x06, (byte) 0xe0, (byte) 0x61, (byte) 0x18, (byte) 0x1e, - (byte) 0x30, (byte) 0xe0, (byte) 0x01, (byte) 0x03, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0xe0, (byte) 0x1f, (byte) 0x1e, - (byte) 0x80, (byte) 0xe1, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x66, (byte) 0x07, (byte) 0x3e, - (byte) 0xb8, (byte) 0xe1, (byte) 0x83, (byte) 0x01, (byte) 0x60, - (byte) 0x86, (byte) 0xf1, (byte) 0x03, (byte) 0x86, (byte) 0x61, - (byte) 0xfc, (byte) 0x18, (byte) 0x66, (byte) 0x18, (byte) 0x1e, - (byte) 0x76, (byte) 0xe0, (byte) 0x66, (byte) 0x00, (byte) 0x3f, - (byte) 0xe0, (byte) 0xf0, (byte) 0x06, (byte) 0x03, (byte) 0x33, - (byte) 0x86, (byte) 0xc1, (byte) 0xe0, (byte) 0x1f, (byte) 0x0c, - (byte) 0x30, (byte) 0xc0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x60, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x20, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x08, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x80, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x33, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x06, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x38, - (byte) 0x30, (byte) 0x70, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1e, - (byte) 0x00, (byte) 0x00, (byte) 0x80, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x06, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x38, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - }, - 10, 16, 14, 10, 96, 32); - } - } - /** - * Large font 20x32 - */ - static class LargeFont extends Font - { - - /** - * - */ - private static final long serialVersionUID = -6556678445133835612L; - - LargeFont() - { - super ( - new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xfc, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xc0, (byte) 0xff, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xfc, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xc0, (byte) 0xff, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x0f, (byte) 0x0c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x0f, (byte) 0x0c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x0c, (byte) 0x0f, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0xc0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xfc, (byte) 0xf0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x0c, (byte) 0x0f, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0xc0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xfc, (byte) 0xf0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0x0c, (byte) 0x03, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0x0c, (byte) 0x03, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0xcf, (byte) 0x03, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xf0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3f, - (byte) 0x3c, (byte) 0xfc, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0xcf, (byte) 0x03, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xf0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3f, - (byte) 0x3c, (byte) 0xfc, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0x0f, (byte) 0x00, (byte) 0xc3, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xcc, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0xcf, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xff, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0xfc, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0x0f, (byte) 0x00, (byte) 0xc3, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xcc, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0xcf, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xff, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0xfc, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xcc, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0xff, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x03, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xcc, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xcf, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0xff, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x03, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x3f, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc3, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xcc, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x3f, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0xf0, (byte) 0x0f, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc3, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0xf0, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x3f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0x0f, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0x3f, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xcc, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xff, (byte) 0x03, (byte) 0x3c, (byte) 0x0c, - (byte) 0x3c, (byte) 0xfc, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x3c, (byte) 0xc3, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xcf, (byte) 0xcf, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xfc, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x3f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xf3, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0xff, (byte) 0x03, (byte) 0x3c, (byte) 0x0c, - (byte) 0x3c, (byte) 0xfc, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x3c, (byte) 0xc3, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xcf, (byte) 0xcf, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xfc, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x3f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xf3, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x0c, (byte) 0x3f, - (byte) 0x0c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xfc, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x30, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x0c, (byte) 0x3f, - (byte) 0x0c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0xfc, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x30, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xf3, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x0f, (byte) 0x33, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x00, - (byte) 0xfc, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xff, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xcf, (byte) 0x03, (byte) 0x0f, (byte) 0x33, - (byte) 0x0c, (byte) 0x30, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x00, - (byte) 0xfc, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xc3, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xff, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0x00, (byte) 0x03, (byte) 0x33, - (byte) 0x0c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x30, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xff, (byte) 0x00, (byte) 0x03, (byte) 0x33, - (byte) 0x0c, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x0f, (byte) 0x3f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xc0, (byte) 0x30, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0x3c, (byte) 0xfc, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x03, (byte) 0x0f, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x03, (byte) 0x3f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0x3c, (byte) 0xfc, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0xf0, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0x00, (byte) 0xcf, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xf0, (byte) 0xf0, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x0f, (byte) 0x3c, - (byte) 0xf0, (byte) 0xf0, (byte) 0x03, (byte) 0x0f, (byte) 0x3c, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0xf3, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x0f, (byte) 0x0f, - (byte) 0xfc, (byte) 0xf0, (byte) 0x00, (byte) 0x03, (byte) 0x3f, - (byte) 0x3c, (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x00, (byte) 0x0c, - (byte) 0xf0, (byte) 0x0f, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0xcf, (byte) 0x03, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xff, (byte) 0x0f, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0x00, (byte) 0xfc, (byte) 0x00, (byte) 0xff, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x00, (byte) 0x0c, - (byte) 0xf0, (byte) 0x0f, (byte) 0x03, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0xc0, (byte) 0x03, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xc0, (byte) 0x3f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0xc0, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0xfc, (byte) 0x3f, (byte) 0xc0, (byte) 0xff, (byte) 0x3f, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0xc3, (byte) 0xff, (byte) 0x3f, - (byte) 0xc0, (byte) 0x3f, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xfc, (byte) 0xff, (byte) 0xc3, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x3c, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0xcf, (byte) 0x03, (byte) 0xfc, (byte) 0x0f, - (byte) 0xc0, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xff, (byte) 0x0f, - (byte) 0x00, (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0xf0, (byte) 0xff, (byte) 0xc0, (byte) 0x03, (byte) 0x3c, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xfc, (byte) 0x03, - (byte) 0x3c, (byte) 0x3f, (byte) 0x00, (byte) 0xfc, (byte) 0x3c, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x0f, - (byte) 0x00, (byte) 0xfc, (byte) 0x00, (byte) 0xff, (byte) 0x3c, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x0f, (byte) 0x0f, - (byte) 0x3c, (byte) 0xc0, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0xfc, (byte) 0xff, (byte) 0x03, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0xf0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x3c, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xf0, (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x3f, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x30, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0f, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xf0, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xfc, (byte) 0x03, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0xc0, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x3c, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x3c, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0xc0, (byte) 0x0f, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x0f, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - }, - 20, 32, 28, 20, 96, 32); - } - } - - /** - * Create a new font for the specified NXT format glyph map - * @param glyphs the actual bytes of the glyph. - * @param width The cell width. - * @param height The cell height. - * @param glyphWidth The width of the glyph bits. - */ - protected Font(byte[] glyphs, int width, int height, int base, int glyphWidth, int count, int first) - { - this.glyphs = glyphs; - this.width = width; - this.height = height; - this.base = base; - this.glyphWidth = glyphWidth; - this.glyphCount = count; - this.firstChar = first; - } - - /** - * Return the system font. - * @return current system font object - */ - public static Font getDefaultFont() - { - if (medium == null) - medium = new MediumFont(); - return medium; - } - - /** - * return the height of the font in pixels. - * @return pixel height - */ - public int getHeight() - { - return height; - } - - /** - * Return the base line position in pixels. This is the offset from the - * top of the font. - * @return base position. - */ - public int getBaselinePosition() - { - return base; - } - - /** - * Return the width of the specified string in pixels - * @param str - * @return width of the string - */ - public int stringWidth(String str) - { - return str.length() * width; - } - - /** - * Request a particular type and size of font. Currently only the size - * parameter is used and it should be one of SIZE_SMALL, SIZE_MEDIUM or - * SIZE_LARGE. - * @param face - * @param style - * @param size - * @return The requested Font - */ - public static Font getFont(int face, int style, int size) - { - if (size == SIZE_SMALL) - return getSmallFont(); - else if (size == SIZE_LARGE) - return getLargeFont(); - else - //return new MediumFont(); - return getDefaultFont(); - } - - // The following non-standard methods can be used to access the additional - // fonts. Using them requires less memory than getFont. - /** - * Return the small font. - * @return the small font - */ - public static synchronized Font getSmallFont() - { - if (small == null) - small = new SmallFont(); - return small; - } - - /** - * Return the large font. - * @return the large font - */ - public static synchronized Font getLargeFont() - { - if (large == null) - large = new LargeFont(); - return large; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/GraphicsLCD.java b/ev3classes/src/main/java/lejos/hardware/lcd/GraphicsLCD.java deleted file mode 100644 index 00eef95..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/GraphicsLCD.java +++ /dev/null @@ -1,359 +0,0 @@ -package lejos.hardware.lcd; - -public interface GraphicsLCD extends CommonLCD { - - public static final int TRANS_MIRROR = 2; - public static final int TRANS_MIRROR_ROT180 = 1; - public static final int TRANS_MIRROR_ROT270 = 4; - public static final int TRANS_MIRROR_ROT90 = 7; - public static final int TRANS_NONE = 0; - public static final int TRANS_ROT180 = 3; - public static final int TRANS_ROT270 = 6; - public static final int TRANS_ROT90 = 5; - - /** - * Centering text and images horizontally - * around the anchor point - * - *

    Value 1 is assigned to HCENTER.

    - */ - public static final int HCENTER = 1; - /** - * Centering images vertically - * around the anchor point. - * - *

    Value 2 is assigned to VCENTER.

    - */ - public static final int VCENTER = 2; - /** - * Position the anchor point of text and images - * to the left of the text or image. - * - *

    Value 4 is assigned to LEFT.

    - */ - public static final int LEFT = 4; - /** - * Position the anchor point of text and images - * to the right of the text or image. - * - *

    Value 8 is assigned to RIGHT.

    - */ - public static final int RIGHT = 8; - /** - * Position the anchor point of text and images - * above the text or image. - * - *

    Value 16 is assigned to TOP.

    - */ - public static final int TOP = 16; - /** - * Position the anchor point of text and images - * below the text or image. - * - *

    Value 32 is assigned to BOTTOM.

    - */ - public static final int BOTTOM = 32; - /** - * Position the anchor point at the baseline of text. - * - *

    Value 64 is assigned to BASELINE.

    - */ - public static final int BASELINE = 64; - /** - * Constant for the SOLID stroke style. - * - *

    Value 0 is assigned to SOLID.

    - */ - public static final int SOLID = 0; - /** - * Constant for the DOTTED stroke style. - * - *

    Value 1 is assigned to DOTTED.

    - */ - public static final int DOTTED = 1; - - /* Public color definitions NOT Standard*/ - public static final int BLACK = 0; - public static final int WHITE = 0xffffff; - - /** - * Method to set a pixel on the screen. - * @param x the x coordinate - * @param y the y coordinate - * @param color the pixel color (0 = white, 1 = black) - */ - public void setPixel(int x, int y, int color); - - /** - * Method to get a pixel from the screen. - * @param x the x coordinate - * @param y the y coordinate - * @return the pixel color (0 = white, 1 = black) - */ - public int getPixel(int x, int y); - - /** - * Draws the specified String using the current font and color. x and y - * give the location of the anchor point. Additional method to allow for - * the easy use of inverted text. In this case the area below the string - * is drawn in the current color, before drawing the text in the "inverted" - * color. - *
    Note: This is a non standard method. - * @param str the String to be drawn - * @param x the x coordinate of the anchor point - * @param y the y coordinate of the anchor point - * @param anchor the anchor point for positioning the text - * @param inverted true to invert the text display. - */ - public void drawString(String str, int x, int y, int anchor, boolean inverted); - - /** - * Draws the specified String using the current font and color. x and y - * give the location of the anchor point. - * @param str the String to be drawn - * @param x the x coordinate of the anchor point - * @param y the y coordinate of the anchor point - * @param anchor the anchor point for positioning the text - */ - public void drawString(String str, int x, int y, int anchor); - - /** - * Draw a substring to the graphics surface using the current color. - * @param str the base string - * @param offset the start of the sub string - * @param len the length of the sub string - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawSubstring(String str, int offset, int len, - int x, int y, int anchor); - - /** - * Draw a single character to the graphics surface using the current color. - * @param character the character to draw - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawChar(char character, int x, int y, int anchor); - - /** - * Draw a series of characters to the graphics surface using the current color. - * @param data the characters - * @param offset the start of the characters to be drawn - * @param length the length of the character string to draw - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawChars(char[] data, int offset, int length, - int x, int y, int anchor); - - /** - * Return the current stroke style. - * @return current style. - */ - public int getStrokeStyle(); - - /** - * Set the stroke style to be used for drawing operations. - * @param style new style. - */ - public void setStrokeStyle(int style); - - /** - * Draw the specified image to the graphics surface, using the supplied rop. - *
    Note: This is a non standard method. - * Added because without it, it is very - * hard to invert/manipulate an image, or screen region - * @param src image to draw (may be null for ops that do not require input. - * @param sx x offset in the source - * @param sy y offset in the source - * @param w width of area to draw - * @param h height of area to draw. - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @param rop drawing operation. - * @see Image - */ - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, int y, int anchor, int rop); - - /** - * Draw the specified region of the source image to the graphics surface - * after applying the requested transformation, use the supplied rop. - *
    NOTE: When calculating the anchor point this method assumes that - * a transformed version of the source width/height should be used. - * @param src The source image - * @param sx x coordinate of the region - * @param sy y coordinate of the region - * @param w width of the region - * @param h height of the region - * @param transform the required transform - * @param x x coordinate of the anchor point - * @param y y coordinate of the anchor point - * @param anchor type of anchor - * @param rop raster operation used to draw the output. - */ - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int transform, int x, int y, int anchor, int rop); - - /** - * Draw the specified region of the supplied image to the graphics surface. - * NOTE: Transforms are not currently supported. - * @param src image to draw (may be null for ops that do not require input. - * @param sx x offset to the region - * @param sy y offset to the region - * @param w width of the region - * @param h height of the region - * @param transform - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @see Image - */ - public void drawRegion(Image src, - int sx, int sy, - int w, int h, - int transform, - int x, int y, - int anchor); - - /** - * Draw the specified image to the graphics surface, using the supplied rop. - * @param src image to draw (may be null for ops that do not require input. - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @see Image - */ - public void drawImage(Image src, int x, int y, int anchor); - - /** - * Draw a line between the specified points, using the current color and style. - * @param x0 x start point - * @param y0 y start point - * @param x1 x end point - * @param y1 y end point - */ - public void drawLine(int x0, int y0, int x1, int y1); - - /** - * Draw an arc, using the current color and style. - * @param x - * @param y - * @param width - * @param height - * @param startAngle - * @param arcAngle - */ - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle); - - /** - * Draw a filled arc, using the current color. - * @param x - * @param y - * @param width - * @param height - * @param startAngle - * @param arcAngle - */ - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle); - - /** - * Draw a rounded rectangle. - * @param x - * @param y - * @param width - * @param height - * @param arcWidth - * @param arcHeight - */ - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight); - - /** - * Draw a rectangle using the current color and style. - * @param x - * @param y - * @param width - * @param height - */ - public void drawRect(int x, int y, int width, int height); - - /** - * Draw a filled rectangle using the current color. - * @param x - * @param y - * @param w - * @param h - */ - public void fillRect(int x, int y, int w, int h); - - /** - * Copy one rectangular area of the drawing surface to another. - * @param sx Source x - * @param sy Source y - * @param w Source width - * @param h Source height - * @param x Destination x - * @param y Destination y - * @param anchor location of the anchor point of the destination. - */ - public void copyArea(int sx, int sy, - int w, int h, - int x, int y, int anchor); - - /** - * Return the currently selected font object. - * @return Current font. - */ - public Font getFont(); - - /** - * Set the current font - * @param f the font - */ - public void setFont(Font f); - - /** - * Translates the origin of the graphics context to the point - * (x, y) in the current coordinate system. Calls are cumulative. - * - * @param x the new translation origin x value - * @param y new translation origin y value - * @see #getTranslateX() - * @see #getTranslateY() - */ - public void translate(int x, int y); - - /** - * Gets the X coordinate of the translated origin of this graphics context. - * @return X of current origin - */ - public int getTranslateX(); - - /** - * Gets the Y coordinate of the translated origin of this graphics context. - * @return Y of current origin - */ - public int getTranslateY(); - - /** - * Set the current drawing color. The value is in the format 0x00RRGGBB. - * NOTE. Currently only black and white is supported. any non black color - * is treated as white! - * @param rgb new color. - */ - public void setColor(int rgb); - - /** - * Sets the current color to the specified RGB values. - * @param red the red component - * @param green the green component - * @param blue the blue - * @throws IllegalArgumentException if any of the color components - * are outside of range 0-255 - */ - public void setColor(int red, int green, int blue); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/Image.java b/ev3classes/src/main/java/lejos/hardware/lcd/Image.java deleted file mode 100644 index 7d18fc1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/Image.java +++ /dev/null @@ -1,198 +0,0 @@ -package lejos.hardware.lcd; - -import java.io.InputStream; -import java.io.IOException; -import java.io.DataInputStream; -import java.io.Serializable; - -import lejos.internal.ev3.EV3GraphicsLCD; - - -/** - * Provides support for in memory images. - * The format of the bitmap is in standard leJOS format (so aligned for use on - * EV3 LCD display). There is one bit per pixel. The pixels are packed into bytes - * with each byte spanning 8 scan lines. The least significant bit of each byte - * is the pixel for the top most scan line, the most significant bit is the - * 8th scan line. Values of 1 represent black. 0 white. This class implements a - * sub set of the standard lcdui Image class. Only mutable images are supported - * and the ARGB methods are not available. - * - * TODO: This file needs to be updated to match the EV3 image format. - * @author Andre Nijholt & Andy Shaw - */ -public class Image implements Serializable -{ - private static final long serialVersionUID = -3934835136206856658L; - - // header is LNI0 => 0x4c4e4930 (big endian) - private static final int LNI0_HEADER = 0x4c4e4930; - - private final int width; - private final int height; - private final byte[] data; - - /** - * Create an image using an already existing byte array. The byte array is - * used to store the image data. The array may already be initialized with - * image data. - *
    Note: This is a non standard constructor. - * @param width width of the image - * @param height height of the image - * @param data The byte array to be used for image store/ - */ - public Image(int width, int height, byte[] data) - { - this.width = width; - this.height = height; - this.data = data; - } - - /** - * Create ablank image of the requested size. - * @param width - * @param height - * @return Returns the new image. - */ - public static Image createImage(int width, int height) - { - byte[] imageData = new byte[width * (height + 7) / 8]; - return new Image(width, height, imageData); - } - - /** - * Read image from file. An image file has the following format: - * - * - * - * - * - * - * - * - * - * - * - * - *
    1st byte - 4th byte5th byte - 8th byte9th byte10th byte ....
    image-width (int)image-height (int)0x00(image data delimit)byte image data....
    - *

    - * For example: - *

    - * After a file with content - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    width (int)height (int)delimitbyte data
    00 00 00 0300 00 00 050000021f
    - * was read, this method will return an object which is equivalent to - *
    new Image(3, 5, new byte[] {(byte)0x00, (byte)0x02, (byte)0x1f})
    - * @param s The input stream for the image file. - * @return an ev3 image object. - * @throws IOException if an input or output error occurs or file format is not correct. - * @see Image - * @see Image#Image(int, int, byte[]) - */ - public static Image createImage(InputStream s) throws IOException - { - DataInputStream in = new DataInputStream(s); - int p, w, h; - p = in.readInt(); - w = in.readUnsignedShort(); - h = in.readUnsignedShort(); - if (p != LNI0_HEADER) - throw new IOException("File format error!"); - - byte[] imageData = new byte[w * ((h + 7) / 8)]; - in.readFully(imageData); - - return new Image(w, h, imageData); - } - - /** - * Creates a new image based upon the transformed region of another image - * @param image Source image - * @param x x co-ordinate of the source region - * @param y y co-ordinate of the source region - * @param w width of the source region - * @param h height of the source region - * @param transform Transform to be applied - * @return New image - */ - public static Image createImage(Image image, int x, int y, int w, int h, int transform) - { - int ow = w; - int oh = h; - // Work out what shape the new image will be... - switch (transform) - { - case GraphicsLCD.TRANS_MIRROR: - case EV3GraphicsLCD.TRANS_MIRROR_ROT180: - case EV3GraphicsLCD.TRANS_ROT180: - case EV3GraphicsLCD.TRANS_NONE: - break; - case EV3GraphicsLCD.TRANS_MIRROR_ROT270: - case EV3GraphicsLCD.TRANS_MIRROR_ROT90: - case EV3GraphicsLCD.TRANS_ROT270: - case EV3GraphicsLCD.TRANS_ROT90: - ow = h; - oh = w; - break; - } - // Create empty new image - Image newImage = createImage(ow, oh); - GraphicsLCD g = newImage.getGraphics(); - g.drawRegion(image, x, y, w, h, transform, 0, 0, 0); - return newImage; - } - - /** - * Return the width of the image. - * @return Image width - */ - public int getWidth() - { - return width; - } - - /** - * return the height of the image. - * @return image height - */ - public int getHeight() - { - return height; - - - } - - /** - * Return the byte array used to hold the image data. - *
    Note: This is a non standard method. - * @return The image byte array. - */ - public byte[] getData() - { - return data; - } - - /** - * Returns a graphics object that can be used to draw to the image. - * @return graphics object. - * @see GraphicsLCD - */ - public GraphicsLCD getGraphics() - { - return new EV3GraphicsLCD(data, width, height); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/LCD.java b/ev3classes/src/main/java/lejos/hardware/lcd/LCD.java deleted file mode 100644 index 65ea60e..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/LCD.java +++ /dev/null @@ -1,307 +0,0 @@ -package lejos.hardware.lcd; - -import lejos.hardware.BrickFinder; -import lejos.utility.Delay; - -/** - * Provide access to the EV3 LCD display - * - */ -//public class LCD extends JPanel -public class LCD -{ - public static final int SCREEN_WIDTH = 178; - public static final int SCREEN_HEIGHT = 128; - public static final int NOOF_CHARS = 96; - public static final int FONT_WIDTH = 10; - public static final int FONT_HEIGHT = 16; - public static final int CELL_WIDTH = FONT_WIDTH; - public static final int CELL_HEIGHT = FONT_HEIGHT; - public static final int DISPLAY_CHAR_WIDTH = SCREEN_WIDTH / CELL_WIDTH; - public static final int DISPLAY_CHAR_DEPTH = SCREEN_HEIGHT / CELL_HEIGHT; - - /** - * Common raster operations for use with bitBlt - */ - public static final int ROP_CLEAR = 0x00000000; - public static final int ROP_AND = 0xff000000; - public static final int ROP_ANDREVERSE = 0xff00ff00; - public static final int ROP_COPY = 0x0000ff00; - public static final int ROP_ANDINVERTED = 0xffff0000; - public static final int ROP_NOOP = 0x00ff0000; - public static final int ROP_XOR = 0x00ffff00; - public static final int ROP_OR = 0xffffff00; - public static final int ROP_NOR = 0xffffffff; - public static final int ROP_EQUIV = 0x00ffffff; - public static final int ROP_INVERT = 0x00ff00ff; - public static final int ROP_ORREVERSE = 0xffff00ff; - public static final int ROP_COPYINVERTED = 0x0000ffff; - public static final int ROP_ORINVERTED = 0xff00ffff; - public static final int ROP_NAND = 0xff0000ff; - public static final int ROP_SET = 0x000000ff; - - protected static TextLCD t = BrickFinder.getDefault().getTextLCD(); - protected static GraphicsLCD g = BrickFinder.getDefault().getGraphicsLCD(); - - private LCD() { - } - - /** - * Standard two input BitBlt function with the LCD display as the - * destination. Supports standard raster ops and - * overlapping images. Images are held in native leJOS/Lego format. - * @param src byte array containing the source image - * @param sw Width of the source image - * @param sh Height of the source image - * @param sx X position to start the copy from - * @param sy Y Position to start the copy from - * @param dx X destination - * @param dy Y destination - * @param w width of the area to copy - * @param h height of the area to copy - * @param rop raster operation. - */ - public static void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, int dy, int w, int h, int rop) - { - g.bitBlt(src, sw, sh, sx, sy, dx, dy, w, h, rop); - } - - /** - * Draw a single char on the LCD at specified x,y co-ordinate. - * @param c Character to display - * @param x X location - * @param y Y location - */ - public static void drawChar(char c, int x, int y) - { - t.drawChar(c, x, y); - } - - public static void clearDisplay() - { - clear(); - } - - /** - * Display an optionally inverted string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - * @param inverted if true the string is displayed inverted. - */ - public static void drawString(String str, int x, int y, boolean inverted) - { - t.drawString(str, x, y, inverted); - } - - /** - * Display a string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public static void drawString(String str, int x, int y) - { - t.drawString(str, x, y); - } - - /** - * Display an int on the LCD at specified x,y co-ordinate. - * - * @param i The value to display. - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public static void drawInt(int i, int x, int y) - { - t.drawInt(i, x, y); - } - - /** - * Display an in on the LCD at x,y with leading spaces to occupy at least the number - * of characters specified by the places parameter. - * - * @param i The value to display - * @param places number of places to use to display the value - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public static void drawInt(int i, int places, int x, int y) - { - t.drawInt(i, places, x, y); - } - - /** - * Start the process of updating the display. This will always return - * immediately after starting the refresh process. - */ - public static void asyncRefresh() - { - t.refresh(); - } - - /** - * Obtain the system time when the current display refresh operation will - * be complete. Not that this may be in the past. - * @return the system time in ms when the refresh will be complete. - */ - public static long getRefreshCompleteTime() - { - return System.currentTimeMillis(); - } - - /** - * Wait for the current refresh cycle to complete. - */ - public static void asyncRefreshWait() - { - long waitTime = getRefreshCompleteTime() - System.currentTimeMillis(); - if (waitTime > 0) - Delay.msDelay(waitTime); - } - - /** - * Refresh the display. If auto refresh is off, this method will wait until - * the display refresh has completed. If auto refresh is on it will return - * immediately. - */ - public static void refresh() - { - t.refresh(); - } - - /** - * Clear the display. - */ - public static void clear() - { - t.clear(); - } - - /** - * Provide access to the LCD display frame buffer. Allows both the firmware - * and Java to make changes. - * @return byte array that is the frame buffer. - */ - public static byte[] getDisplay() - { - return t.getDisplay(); - } - - /** - * Provide access to the LCD system font. Allows both the firmware - * and Java to share the same font bitmaps. - * @return byte array that is the frame buffer. - */ - public static byte[] getSystemFont() - { - return Font.getDefaultFont().glyphs; - } - - /** - * Set the period used to perform automatic refreshing of the display. - * A period of 0 disables the refresh. - * @param period time in ms - * @return the previous refresh period. - */ - public static int setAutoRefreshPeriod(int period) - { - return 0; - } - - /** - * Turn on/off the automatic refresh of the LCD display. At system startup - * auto refresh is on. - * @param on true to enable, false to disable - */ - public static void setAutoRefresh(boolean on) - { - g.setAutoRefresh(on); - } - - /** - * Method to set a pixel on the screen. - * @param x the x coordinate - * @param y the y coordinate - * @param color the pixel color (0 = white, 1 = black) - */ - public static void setPixel(int x, int y, int color) - { - g.setPixel(x, y, color); - } - - /** - * Method to get a pixel from the screen. - * @param x the x coordinate - * @param y the y coordinate - * @return the pixel color (0 = white, 1 = black) - */ - public static int getPixel(int x, int y) { - return g.getPixel(x, y); - } - - /** - * Standard two input BitBlt function. Supports standard raster ops and - * overlapping images. Images are held in native leJOS/Lego format. - * @param src byte array containing the source image - * @param sw Width of the source image - * @param sh Height of the source image - * @param sx X position to start the copy from - * @param sy Y Position to start the copy from - * @param dst byte array containing the destination image - * @param dw Width of the destination image - * @param dh Height of the destination image - * @param dx X destination - * @param dy Y destination - * @param w width of the area to copy - * @param h height of the area to copy - * @param rop raster operation. - */ - public static 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) - { - g.bitBlt(src, sw, sh, sx, sy, dst, dw, dh, dx, dy, w, h, rop); - } - - /** - * Scrolls the screen up one text line - * - */ - public static void scroll() - { - t.scroll(); - } - - /** - * Clear a contiguous set of characters - * @param x the x character coordinate - * @param y the y character coordinate - * @param n the number of characters - */ - public static void clear(int x, int y, int n) { - t.clear(); - } - - /** - * Clear an LCD display row - * @param y the row to clear - */ - public static void clear(int y) { - t.clear(y); - } - - /** - * Set the LCD contrast. - * @param contrast 0 blank 0x60 full on - */ - public static void setContrast(int contrast) - { - // Not implemented - } - - public static byte[] getHWDisplay() { - return t.getHWDisplay(); - } -} - diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/LCDOutputStream.java b/ev3classes/src/main/java/lejos/hardware/lcd/LCDOutputStream.java deleted file mode 100644 index e6b764c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/LCDOutputStream.java +++ /dev/null @@ -1,71 +0,0 @@ -package lejos.hardware.lcd; - -import java.io.OutputStream; - -import lejos.hardware.BrickFinder; - -/** - * A simple output stream that implements console output. - * It writes to the bottom line of the screen, scrolling the - * LCD up one line when writing to character position 0, - * and starting a new line when the position reaches 16 - * or a new line character is written. - * - * Used by System.out.println. - * - * @author Lawrie Griffiths - * - */ -public class LCDOutputStream extends OutputStream { - private int col = 0; - private int line = 0; - - private TextLCD lcd; - - public LCDOutputStream(TextLCD lcd) - { - this.lcd = lcd; - } - - public LCDOutputStream() - { - this(BrickFinder.getDefault().getTextLCD()); - } - - @Override - public void write(int c) { - char x = (char)(c & 0xFF); - switch (x) - { - case '\f': - lcd.clear(); - line = 0; - col = 0; - break; - case '\t': - col = col + 8 - col % 8; - break; - case '\n': - incLine(); - case '\r': - col = 0; - break; - default: - if (col >= lcd.getTextWidth()) - { - col = 0; - incLine(); - } - lcd.drawChar(x, col++, line); - } - - } - - private void incLine() { - lcd.refresh(); - if (line < lcd.getTextHeight() - 1) - line++; - else - lcd.scroll(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/TextLCD.java b/ev3classes/src/main/java/lejos/hardware/lcd/TextLCD.java deleted file mode 100644 index f22a3f8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/TextLCD.java +++ /dev/null @@ -1,86 +0,0 @@ -package lejos.hardware.lcd; - -public interface TextLCD extends CommonLCD { - - /** - * Draw a single char on the LCD at specified x,y co-ordinate. - * @param c Character to display - * @param x X location - * @param y Y location - */ - public void drawChar(char c, int x, int y); - - /** - * Display an optionally inverted string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - * @param inverted if true the string is displayed inverted. - */ - public void drawString(String str, int x, int y, boolean inverted); - - /** - * Display a string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawString(String str, int x, int y); - - /** - * Display an int on the LCD at specified x,y co-ordinate. - * - * @param i The value to display. - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawInt(int i, int x, int y); - - /** - * Display an in on the LCD at x,y with leading spaces to occupy at least the number - * of characters specified by the places parameter. - * - * @param i The value to display - * @param places number of places to use to display the value - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawInt(int i, int places, int x, int y); - - /** - * Clear a contiguous set of characters - * @param x the x character coordinate - * @param y the y character coordinate - * @param n the number of characters - */ - public void clear(int x, int y, int n); - - /** - * Clear an LCD display row - * @param y the row to clear - */ - public void clear(int y); - - /** - * Scrolls the screen up one text line - */ - public void scroll(); - - /** - * Get the current font - */ - public Font getFont(); - - /** - * Get the width of the screen in characters - */ - public int getTextWidth(); - - /** - * Get the height of the screen in characters - */ - public int getTextHeight(); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/lcd/package-info.java b/ev3classes/src/main/java/lejos/hardware/lcd/package-info.java deleted file mode 100644 index 2f529bb..0000000 --- a/ev3classes/src/main/java/lejos/hardware/lcd/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Access to the EV3 LCD - */ -package lejos.hardware.lcd; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/motor/BaseRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/BaseRegulatedMotor.java deleted file mode 100644 index 27eaf88..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/BaseRegulatedMotor.java +++ /dev/null @@ -1,429 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.Device; -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -//import lejos.internal.ev3.EV3MotorPort; -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; -/** - * Abstraction for a Regulated motor motor. - * The basic control methods are: - * forward, backward, reverseDirection, stop - * and flt. To set each motor's velocity, use {@link #setSpeed(int) - * setSpeed }. - * The maximum velocity of the motor is limited by the battery voltage and load. - * With no load, the maximum degrees per second is about 100 times the voltage - * (for the large EV3 motor).
    - * The velocity is regulated by comparing the tacho count with velocity times elapsed - * time, and adjusting motor power to keep these closely matched. Changes in velocity - * will be made at the rate specified via the - * setAcceleration(int acceleration) method. - * The methods rotate(int angle) and rotateTo(int ange) - * use the tachometer to control the position at which the motor stops, usually within 1 degree - * or 2.
    - *
    Listeners. An object implementing the {@link lejos.robotics.RegulatedMotorListener - * RegulatedMotorListener } interface may register with this class. - * It will be informed each time the motor starts or stops. - *
    Stall detection If a stall is detected or if for some other reason - * the speed regulation fails, the motor will stop, and - * isStalled() returns true. - *
    Motors will hold their position when stopped. If this is not what you require use - * the flt() method instead of stop(). - *
    - *

    - * Example:

    - *

    - *   Motor.A.setSpeed(720);// 2 RPM
    - *   Motor.C.setSpeed(720);
    - *   Motor.A.forward();
    - *   Motor.C.forward();
    - *   Delay.msDelay(1000);
    - *   Motor.A.stop();
    - *   Motor.C.stop();
    - *   Motor.A.rotateTo( 360);
    - *   Motor.A.rotate(-720,true);
    - *   while(Motor.A.isMoving()Thread.yield();
    - *   int angle = Motor.A.getTachoCount(); // should be -360
    - *   LCD.drawInt(angle,0,0);
    - * 
    - * TODO: Fix the name - * @author Roger Glassey/Andy Shaw - */ -public abstract class BaseRegulatedMotor extends Device implements RegulatedMotor -{ - // 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; - protected static final int NO_LIMIT = 0x7fffffff; - protected final MotorRegulator reg; - protected TachoMotorPort tachoPort; - protected float speed = 360; - protected int acceleration = 6000; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public BaseRegulatedMotor(TachoMotorPort port, MotorRegulator regulator, - int typ, float moveP, float moveI, float moveD, float holdP, float holdI, float holdD, int offset, int maxSpeed) - { - tachoPort = port; - // Use default regulator if non specified - if (regulator == null) - reg = port.getRegulator(); - else - reg = regulator; - MAX_SPEED_AT_9V = maxSpeed; - reg.setControlParamaters(typ, moveP, moveI, moveD, holdP, holdI, holdD, offset); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public BaseRegulatedMotor(Port port, MotorRegulator regulator, int typ, float moveP, float moveI, - float moveD, float holdP, float holdI, float holdD, int offset, int maxSpeed) - { - this(port.open(TachoMotorPort.class), regulator, typ, moveP, moveI, moveD, holdP, holdI, holdD, offset, maxSpeed); - releaseOnClose(tachoPort); - } - - /** - * Close the motor regulator. Release the motor from regulation and free any - * associated resources. - */ - public void close() - { - suspendRegulation(); - super.close(); - } - - /** - * Removes this motor from the motor regulation system. After this call - * the motor will be in float mode and will have stopped. Note calling any - * of the high level move operations (forward, rotate etc.), will - * automatically enable regulation. - * @return true iff regulation has been suspended. - */ - public boolean suspendRegulation() - { - // Putting the motor into float mode disables regulation. note - // that we wait for the operation to complete. - reg.newMove(0, acceleration, NO_LIMIT, false, true); - return true; - } - - - /** - * @return the current tachometer count. - * @see lejos.robotics.RegulatedMotor#getTachoCount() - */ - public int getTachoCount() - { - return reg.getTachoCount(); - } - - /** - * Returns the current position that the motor regulator is trying to - * maintain. Normally this will be the actual position of the motor and will - * be the same as the value returned by getTachoCount(). However in some - * circumstances (activeMotors that are in the process of stalling, or activeMotors - * that have been forced out of position), the two values may differ. Note that - * if regulation has been suspended calling this method will restart it. - * @return the current position calculated by the regulator. - */ - public float getPosition() - { - return reg.getPosition(); - } - - /** - * @see lejos.hardware.motor.BasicMotor#forward() - */ - public void forward() - { - reg.newMove(speed, acceleration, +NO_LIMIT, true, false); - } - - /** - * @see lejos.hardware.motor.BasicMotor#backward() - */ - public void backward() - { - reg.newMove(speed, acceleration, -NO_LIMIT, true, false); - } - - /** - * Set the motor into float mode. This will stop the motor without braking - * and the position of the motor will not be maintained. - */ - public void flt() - { - reg.newMove(0, acceleration, NO_LIMIT, false, true); - } - - /** - * Set the motor into float mode. This will stop the motor without braking - * and the position of the motor will not be maintained. - * @param immediateReturn If true do not wait for the motor to actually stop - */ - public void flt(boolean immediateReturn) - { - reg.newMove(0, acceleration, NO_LIMIT, false, !immediateReturn); - } - - /** - * Causes motor to stop, pretty much - * instantaneously. In other words, the - * motor doesn't just stop; it will resist - * any further motion. - * Cancels any rotate() orders in progress - */ - public void stop() - { - reg.newMove(0, acceleration, NO_LIMIT, true, true); - } - - /** - * Causes motor to stop, pretty much - * instantaneously. In other words, the - * motor doesn't just stop; it will resist - * any further motion. - * Cancels any rotate() orders in progress - * @param immediateReturn if true do not wait for the motor to actually stop - */ - public void stop(boolean immediateReturn) - { - reg.newMove(0, acceleration, NO_LIMIT, true, !immediateReturn); - } - - /** - * This method returns true if the motor is attempting to rotate. - * The return value may not correspond to the actual motor movement.
    - * For example, If the motor is stalled, isMoving() will return true.
    - * After flt() is called, this method will return false even though the motor - * axle may continue to rotate by inertia. - * If the motor is stalled, isMoving() will return true. . A stall can - * be detected by calling {@link #isStalled()}; - * @return true iff the motor is attempting to rotate.
    - */ - public boolean isMoving() - { - return reg.isMoving(); - } - - /** - * Wait until the current movement operation is complete (this can include - * the motor stalling). - */ - public void waitComplete() - { - reg.waitComplete(); - } - - public void rotateTo(int limitAngle, boolean immediateReturn) - { - reg.newMove(speed, acceleration, limitAngle, true, !immediateReturn); - } - - /** - * Sets desired motor speed , in degrees per second; - * The maximum reliably sustainable velocity is 100 x battery voltage under - * moderate load, such as a direct drive robot on the level. - * @param speed value in degrees/sec - */ - public void setSpeed(int speed) - { - this.speed = Math.abs(speed); - reg.adjustSpeed(this.speed); - } - - /** - * Sets desired motor speed , in degrees per second; - * The maximum reliably sustainable velocity is 100 x battery voltage under - * moderate load, such as a direct drive robot on the level. - * @param speed value in degrees/sec - */ - public void setSpeed(float speed) - { - this.speed = Math.abs(speed); - reg.adjustSpeed(this.speed); - } - - /** - * sets the acceleration rate of this motor in degrees/sec/sec
    - * The default value is 6000; Smaller values will make speeding up. or stopping - * at the end of a rotate() task, smoother; - * @param acceleration - */ - public void setAcceleration(int acceleration) - { - this.acceleration = Math.abs(acceleration); - reg.adjustAcceleration(this.acceleration); - } - - /** - * returns acceleration in degrees/second/second - * @return the value of acceleration - */ - public int getAcceleration() - { - return acceleration; - } - - /** - * Return the angle that this Motor is rotating to. - * @return angle in degrees - */ - public int getLimitAngle() - { - return reg.getLimitAngle(); - } - - /** - * Reset the tachometer associated with this motor. Note calling this method - * will cause any current move operation to be halted. - */ - public void resetTachoCount() - { - reg.resetTachoCount(); - } - - /** - * Add a motor listener. Move operations will be reported to this object. - * @param listener - */ - public void addListener(RegulatedMotorListener listener) - { - reg.addListener(this, listener); - } - - public RegulatedMotorListener removeListener() - { - return reg.removeListener(); - } - - /** - * Rotate by the request number of degrees. - * @param angle number of degrees to rotate relative to the current position - * @param immediateReturn if true do not wait for the move to complete - */ - public void rotate(int angle, boolean immediateReturn) - { - rotateTo(Math.round(reg.getPosition()) + angle, immediateReturn); - } - - /** - * Rotate by the requested number of degrees. Wait for the move to complete. - * @param angle - */ - public void rotate(int angle) - { - rotate(angle, false); - } - - /** - * Rotate to the target angle. Do not return until the move is complete. - * @param limitAngle Angle to rotate to. - */ - public void rotateTo(int limitAngle) - { - rotateTo(limitAngle, false); - } - - /** - * Return the current target speed. - * @return the current target speed. - */ - public int getSpeed() - { - return Math.round(speed); - } - - - /** - * @deprecated The regulator will always try to hold position unless the - * motor is set into float mode using flt(). - * @param power - a value between 1 and 100; - */ - @Deprecated - public void lock(int power) - { - stop(false); - } - - /** - * Return true if the motor is currently stalled. - * @return true if the motor is stalled, else false - */ - public boolean isStalled() - { - return reg.isStalled(); - } - - /** - * Set the parameters for detecting a stalled motor. A motor will be recognised - * as stalled if the movement error (the amount the motor lags the regulated - * position) is greater than error for a period longer than time. - * @param error The error threshold - * @param time The time that the error threshold needs to be exceeded for. - */ - public void setStallThreshold(int error, int time) - { - reg.setStallThreshold(error, time); - } - /** - * Return the current velocity. - * @return current velocity in degrees/s - */ - public int getRotationSpeed() - { - return Math.round(reg.getCurrentVelocity()); - } - - - public float getMaxSpeed() { - // It is generally assumed, that the maximum accurate speed of an EV3 Motor is - // 100 degree/second * Voltage. We generalise this to other LEGO motors by returning a value - // that is based on 90% of the maximum free running speed of the motor. - // TODO: Should this be using the Brick interface? - // TODO: If we ever allow the regulator class be remote, then we will need to ensure we - // get the voltage of the remote brick not the local one. - return LocalEV3.ev3.getPower().getVoltage() * MAX_SPEED_AT_9V/9.0f * 0.9f; - } - - /** - * Specify a set of motors that should be kept in synchronization with this one. - * The synchronization mechanism simply ensures that operations between a startSynchronization - * call and an endSynchronization call will all be executed at the same time (when the - * endSynchronization method is called). This is all that is needed to ensure that motors - * will operate in a synchronized fashion. The start/end methods can also be used to ensure - * that reads of the motor state will also be consistent. - * @param syncList an array of motors to synchronize with. - */ - public void synchronizeWith(RegulatedMotor[] syncList) - { - // Create list of regualtors and pass it on! - MotorRegulator[] rl = new MotorRegulator[syncList.length]; - for(int i = 0; i < syncList.length; i++) - rl[i] = ((BaseRegulatedMotor)syncList[i]).reg; - reg.synchronizeWith(rl); - } - - /** - * Begin a set of synchronized motor operations - */ - public void startSynchronization() - { - reg.startSynchronization(); - } - - /** - * Complete a set of synchronized motor operations. - */ - public void endSynchronization() - { - reg.endSynchronization(true); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/BasicMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/BasicMotor.java deleted file mode 100644 index b31c1df..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/BasicMotor.java +++ /dev/null @@ -1,94 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.Device; -import lejos.hardware.port.BasicMotorPort; -import lejos.robotics.DCMotor; - -/** - * Abstraction for basic motor operations. - * - * @author Lawrie Griffiths. - * - */ -public abstract class BasicMotor extends Device implements DCMotor -{ - protected static int INVALID_MODE = -1; - protected int mode = INVALID_MODE; - protected BasicMotorPort port; - protected int power = 0; - - public void setPower(int power) - { - this.power = power; - port.controlMotor(power, mode); - } - - public int getPower() - { - return power; - } - - /** - * Update the internal state tracking the motor direction - * @param newMode - */ - protected void updateState( int newMode) - { - if (newMode == mode) return; - mode = newMode; - port.controlMotor(power, newMode); - } - - /** - * Causes motor to rotate forward. - */ - public void forward() - { - updateState( BasicMotorPort.FORWARD); - } - - - /** - * Causes motor to rotate backwards. - */ - public void backward() - { - updateState( BasicMotorPort.BACKWARD); - } - - - /** - * Returns true iff the motor is in motion. - * - * @return true iff the motor is currently in motion. - */ - public boolean isMoving() - { - return (mode == BasicMotorPort.FORWARD || mode == BasicMotorPort.BACKWARD); - } - - /** - * Causes motor to float. The motor will lose all power, - * but this is not the same as stopping. Use this - * method if you don't want your robot to trip in - * abrupt turns. - */ - public void flt() - { - updateState( BasicMotorPort.FLOAT); - } - - - /** - * Causes motor to stop, pretty much - * instantaneously. In other words, the - * motor doesn't just stop; it will resist - * any further motion. - * Cancels any rotate() orders in progress - */ - public void stop() - { - updateState( BasicMotorPort.STOP); - } -} - diff --git a/ev3classes/src/main/java/lejos/hardware/motor/EV3LargeRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/EV3LargeRegulatedMotor.java deleted file mode 100644 index d2a5b14..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/EV3LargeRegulatedMotor.java +++ /dev/null @@ -1,44 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a Large Lego EV3/NXT motor. - * - */ -public class EV3LargeRegulatedMotor extends BaseRegulatedMotor -{ - static final float MOVE_P = 4f; - static final float MOVE_I = 0.04f; - static final float MOVE_D = 10f; - static final float HOLD_P = 2f; - static final float HOLD_I = 0.02f; - static final float HOLD_D = 8f; - static final int OFFSET = 0; - - private static final int MAX_SPEED = 175*360/60; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public EV3LargeRegulatedMotor(TachoMotorPort port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public EV3LargeRegulatedMotor(Port port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/EV3MediumRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/EV3MediumRegulatedMotor.java deleted file mode 100644 index c694ccd..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/EV3MediumRegulatedMotor.java +++ /dev/null @@ -1,44 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a Medium Lego EV3/NXT motor. - * - */ -public class EV3MediumRegulatedMotor extends BaseRegulatedMotor -{ - static final float MOVE_P = 8f; - static final float MOVE_I = 0.04f; - static final float MOVE_D = 8f; - static final float HOLD_P = 8f; - static final float HOLD_I = 0.02f; - static final float HOLD_D = 0f; - static final int OFFSET = 1000; - - private static final int MAX_SPEED = 260*360/60; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public EV3MediumRegulatedMotor(TachoMotorPort port) - { - super(port, null, EV3SensorConstants.TYPE_MINITACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public EV3MediumRegulatedMotor(Port port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/JavaMotorRegulator.java b/ev3classes/src/main/java/lejos/hardware/motor/JavaMotorRegulator.java deleted file mode 100644 index 5bbf896..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/JavaMotorRegulator.java +++ /dev/null @@ -1,595 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.TachoMotorPort; -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; -import lejos.utility.Delay; - -/** - * Java based regulator - * regulate velocity; also stop motor at desired rotation angle. - * This class uses a very simple movement model based on simple linear - * acceleration. This model is used to generate ideal target positions which - * are then used to generate error terms between the actual and target position - * this error term is then used to drive a PID style motor controller to - * regulate the power supplied to the motor. - * - * If new command are issued while a move is in progress, the new command - * is blended with the current one to provide smooth movement. - * - * If the requested speed is not possible then the controller will simply - * drop move cycles until the motor catches up with the ideal position. If - * too many consecutive dropped moves are required then the motor is viewed - * to have stalled and the move is terminated. - * - * Once the motor stops, the final position is held using the same PID control - * mechanism (with slightly different parameters), as that used for movement. - * - * TODO: Should we add synchronization to this? - **/ -public class JavaMotorRegulator implements MotorRegulator -{ - // PID constants for move and for hold - // Old values - //static final float MOVE_P = 4f; - //static final float MOVE_I = 0.04f; - //static final float MOVE_D = 32f; - // New values - //static final float MOVE_P = 7f; - //static final float MOVE_P = 6f; - //static final float MOVE_I = 0.04f; - //static final float MOVE_D = 22f; - //static final float MOVE_P = 4f; - //static final float MOVE_I = 0.04f; - //static final float MOVE_D = 10f; - static final float MOVE_P = 4f; - static final float MOVE_I = 0.04f; - static final float MOVE_D = 10f; - static final float HOLD_P = 2f; - static final float HOLD_I = 0.02f; - static final float HOLD_D = 8f; - - float moveP; - float moveI; - float moveD; - float holdP; - float holdI; - float holdD; - float basePower = 0; //used to calculate power - float err1 = 0; // used in smoothing - float err2 = 0; // used in smoothing - float curVelocity = 0; - float baseVelocity = 0; - float baseCnt = 0; - float curCnt = 0; - float curAcc = 0; - float curStopAcc = 0; - float curTargetVelocity = 0; - int curLimit = NO_LIMIT; - boolean curHold = true; - float accCnt = 0; - long baseTime = 0; - long now = 0; - long accTime = 0; - boolean moving = false; - boolean pending = false; - boolean checkLimit = false; - float newSpeed = 0; - int newAcceleration = 0; - int newLimit = 0; - boolean newHold = true; - int tachoCnt; - int zeroTachoCnt; - public int power; - int mode; - boolean active = false; - RegulatedMotorListener listener; - RegulatedMotor motor; - boolean stalled; - int stallCnt = 0; - protected int stallLimit = 50; - protected int stallTime = 1000; - protected TachoMotorPort tachoPort; - protected static final Controller cont = new Controller(); - static { - // Start the single controller thread - cont.setPriority(Thread.MAX_PRIORITY); - cont.setDaemon(true); - // Mark it as system thread, so it won't happen to get suspended during debugging. - //VM.updateThreadFlags(cont, VM.VM_THREAD_SYSTEM, 0); - cont.start(); - // Add shutdown handler to stop the motors - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() {cont.shutdown();} - }); - } - - public JavaMotorRegulator(TachoMotorPort p) - { - tachoPort = p; - tachoPort.setPWMMode(TachoMotorPort.PWM_BRAKE); - reset(); - } - - - public int getTachoCount() - { - return tachoPort.getTachoCount() - zeroTachoCnt; - } - - public synchronized void resetTachoCount() - { - newMove(0, 1000, NO_LIMIT, false, true); - zeroTachoCnt = tachoPort.getTachoCount(); - reset(); - } - - public boolean isMoving() - { - return moving; - } - - public float getCurrentVelocity() - { - return curVelocity; - } - - public void setStallThreshold(int error, int time) - { - this.stallLimit = error; - this.stallTime = time/Controller.UPDATE_PERIOD; - } - - - /** - * Update the internal state of the motor. - * @param velocity - * @param hold - * @param stalled - */ - protected synchronized void updateState(int velocity, boolean hold, boolean stalled) - { - if (listener != null) - { - if (velocity == 0) - listener.rotationStopped(motor, getTachoCount(), stalled, System.currentTimeMillis()); - else - listener.rotationStarted(motor, getTachoCount(), false, System.currentTimeMillis()); - } - } - - @Override - public void addListener(RegulatedMotor motor, RegulatedMotorListener listener) - { - this.motor = motor; - this.listener = listener; - } - - - @Override - public RegulatedMotorListener removeListener() - { - RegulatedMotorListener old = listener; - listener = null; - return old; - } - - - - @Override - public void setControlParamaters(int typ, float moveP, float moveI, - float moveD, float holdP, float holdI, float holdD, int offset) - { - // Stop the motor if needed - newMove(0, 1000, NO_LIMIT, false, true); - this.moveP = moveP; - this.moveI = moveI; - this.moveD = moveD; - this.holdP = holdP; - this.holdI = holdI; - this.holdD = holdD; - reset(); - } - - - @Override - public void waitComplete() - { - waitStop(); - } - - - @Override - public int getLimitAngle() - { - return curLimit; - } - - - @Override - public boolean isStalled() - { - return stalled; - } - - - /** - * Reset the tachometer readings - */ - protected synchronized void reset() - { - curCnt = tachoCnt = getTachoCount(); - baseTime = now = System.currentTimeMillis(); - } - - /** - * Helper method. Start a sub move operation. A sub move consists - * of acceleration/deceleration to a set velocity and then holding that - * velocity up to an optional limit point. If a limit point is set this - * method will be called again to initiate a controlled deceleration - * to that point - * @param speed - * @param acceleration - * @param limit - * @param hold - */ - synchronized private void startSubMove(float speed, float acceleration, int limit, boolean hold) - { - float absAcc = Math.abs(acceleration); - checkLimit = Math.abs(limit) != NO_LIMIT; - baseTime = now; - if (!moving && Math.abs(limit - curCnt) < 1.0) - curTargetVelocity = 0; - else - curTargetVelocity = (limit - curCnt >= 0 ? speed : -speed); - curAcc = curTargetVelocity - curVelocity >= 0 ? absAcc : -absAcc; - curStopAcc = curTargetVelocity >= 0 ? absAcc : -absAcc; - accTime = Math.round(((curTargetVelocity - curVelocity) / curAcc) * 1000); - accCnt = (curVelocity + curTargetVelocity) * accTime / (2 * 1000); - baseCnt = curCnt; - baseVelocity = curVelocity; - curHold = hold; - curLimit = limit; - //limitAngle = curLimit; // limitAngle is in outer. KPT 5/13/2011 06:42 - moving = curTargetVelocity != 0 || baseVelocity != 0; - } - - /** - * Helper method, if move is currently active wait for it to be - * completed - */ - private void waitStop() - { - if (moving) - try - { - wait(); - } catch (Exception e) - { - } - } - - /** - * return the regulations models current position. Ensure that the motor is active - * if needed. - * @return the models current position - */ - synchronized public float getPosition() - { - if (!active) - { - cont.addMotor(this); - active = true; - } - return curCnt; - - } - - /** - * Initiate a new move and optionally wait for it to complete. - * If some other move is currently executing then ensure that this move - * is terminated correctly and then start the new move operation. - * @param speed - * @param acceleration - * @param limit - * @param hold - * @param waitComplete - */ - synchronized public void newMove(float speed, int acceleration, int limit, boolean hold, boolean waitComplete) - { - if (!active) - { - cont.addMotor(this); - active = true; - } - // ditch any existing pending command - pending = false; - // no longer stalled - stalled = false; - // Stop moves always happen now - if (speed == 0) - startSubMove(0, acceleration, NO_LIMIT, hold); - else if (!moving) - { - // not moving so we start a new move - startSubMove(speed, acceleration, limit, hold); - updateState(Math.round(curTargetVelocity), hold, false); - } - else - { - // we already have a move in progress can we modify it to match - // the new request? We must ensure that the new move is in the - // same direction and that any stop will not exceed the current - // acceleration request. - float moveLen = limit - curCnt; - float acc = (curVelocity*curVelocity)/(2*(moveLen)); - if (moveLen*curVelocity >= 0 && Math.abs(acc) <= acceleration) - startSubMove(speed, acceleration, limit, hold); - else - { - // Save the requested move - newSpeed = speed; - newAcceleration = acceleration; - newLimit = limit; - newHold = hold; - pending = true; - // stop the current move - startSubMove(0, acceleration, NO_LIMIT, true); - // If we need to wait for the existing command to end - if (waitComplete) - waitStop(); - } - } - if (waitComplete) - waitStop(); - } - - /** - * The target speed has been changed. Reflect this change in the - * regulator. - * @param newSpeed new target speed. - */ - public synchronized void adjustSpeed(float newSpeed) - { - if (curTargetVelocity != 0) - { - startSubMove(newSpeed, curAcc, curLimit, curHold); - } - if (pending) - this.newSpeed = newSpeed; - } - - /** - * The target acceleration has been changed. Updated the regulator. - * @param newAcc - */ - public synchronized void adjustAcceleration(int newAcc) - { - if (curTargetVelocity != 0) - { - startSubMove(Math.abs(curTargetVelocity), newAcc, curLimit, curHold); - } - if (pending) - newAcceleration = newAcc; - } - - /** - * The move has completed either by the motor stopping or by it stalling - * @param stalled - */ - synchronized private void endMove(boolean stalled) - { - moving = pending; - this.stalled = stalled; - updateState(0, curHold, stalled); - if (stalled) - { - // stalled try and maintain current position - reset(); - curVelocity = 0; - stallCnt = 0; - startSubMove(0, 0, NO_LIMIT, curHold); - } - // if we have a new move, go start it - if (pending) - { - pending = false; - startSubMove(newSpeed, newAcceleration, newLimit, newHold); - updateState(Math.round(curTargetVelocity), curHold, false); - } - notifyAll(); - } - - /** - * Monitors time and tachoCount to regulate velocity and stop motor rotation at limit angle - */ - synchronized void regulateMotor(long delta) - { - float error; - now += delta; - long elapsed = now - baseTime; - if (moving) - { - if (elapsed < accTime) - { - // We are still accelerating, calculate new position - curVelocity = baseVelocity + curAcc * elapsed / (1000); - curCnt = baseCnt + (baseVelocity + curVelocity) * elapsed / (2 * 1000); - error = curCnt - tachoCnt; - } else - { - // no longer accelerating, calculate new position - curVelocity = curTargetVelocity; - curCnt = baseCnt + accCnt + curVelocity * (elapsed - accTime) / 1000; - error = curCnt - tachoCnt; - // Check to see if the move is complete - if (curTargetVelocity == 0 && (pending || (Math.abs(error) < 2 && elapsed > accTime + 100) || elapsed > accTime + 500)) - { - endMove(false); - } - } - // check for stall - if (Math.abs(error) > stallLimit) - { - baseTime += delta; - if (stallCnt++ > stallTime) endMove(true); - } - else - { - stallCnt /= 2; - } - calcPower(error, MOVE_P, MOVE_I, MOVE_D, (float)delta/Controller.UPDATE_PERIOD); - // If we have a move limit, check for time to start the deceleration stage - if (checkLimit) - { - float acc = (curVelocity*curVelocity)/(2*(curLimit - curCnt)); - if (curStopAcc/acc < 1.0) - startSubMove(0, acc, NO_LIMIT, curHold); - } - } else if (curHold) - { - // not moving, hold position - error = curCnt - tachoCnt; - calcPower(error, HOLD_P, HOLD_I, HOLD_D, (float)delta/Controller.UPDATE_PERIOD); - } - else - { - // Allow the motor to move freely - curCnt = tachoCnt; - power = 0; - mode = TachoMotorPort.FLOAT; - active = false; - cont.removeMotor(this); - } - }// end run - - /** - * helper method for velocity regulation. - * calculates power from error using double smoothing and PID like - * control - * @param error - */ - private void calcPower(float error, float P, float I, float D, float time) - { - // use smoothing to reduce the noise in frequent tacho count readings - // New values - err1 = 0.375f * err1 + 0.625f * error; // fast smoothing - err2 = 0.75f * err2 + 0.25f * error; // slow smoothing - // Original values - //err1 = 0.5f * err1 + 0.5f * error; // fast smoothing - //err2 = 0.8f * err2 + 0.2f * error; // slow smoothing - float newPower = basePower + P * err1 + D * (err1 - err2)/time; - basePower = basePower + I * (newPower - basePower)*time; - if (basePower > TachoMotorPort.MAX_POWER) - basePower = TachoMotorPort.MAX_POWER; - else if (basePower < -TachoMotorPort.MAX_POWER) - basePower = -TachoMotorPort.MAX_POWER; - //newPower = (float) (power*0.75 + newPower*0.25); - power = (newPower > TachoMotorPort.MAX_POWER ? TachoMotorPort.MAX_POWER : newPower < -TachoMotorPort.MAX_POWER ? -TachoMotorPort.MAX_POWER : Math.round(newPower)); - - //mode = (power == 0 ? TachoMotorPort.STOP : TachoMotorPort.FORWARD); - mode = TachoMotorPort.FORWARD; - } - - - /** - * This class provides a single thread that drives all of the motor regulation - * process. Only active motors will be regulated. To try and keep motors - * as closely synchronized as possible tach counts for all motors are gathered - * as close as possible to the same time. Similarly new power levels for each - * motor are also set at the same time. - */ - protected static class Controller extends Thread - { - static final int UPDATE_PERIOD = 4; - JavaMotorRegulator [] activeMotors = new JavaMotorRegulator[0]; - boolean running = false; - - /** - * Add a motor to the set of active motors. - * @param m - */ - synchronized void addMotor(JavaMotorRegulator m) - { - JavaMotorRegulator [] newMotors = new JavaMotorRegulator[activeMotors.length+1]; - System.arraycopy(activeMotors, 0, newMotors, 0, activeMotors.length); - newMotors[activeMotors.length] = m; - m.reset(); - activeMotors = newMotors; - } - - /** - * Remove a motor from the set of active motors. - * @param m - */ - synchronized void removeMotor(JavaMotorRegulator m) - { - m.tachoPort.controlMotor(0, TachoMotorPort.FLOAT); - JavaMotorRegulator [] newMotors = new JavaMotorRegulator[activeMotors.length-1]; - int j = 0; - for(int i = 0; i < activeMotors.length; i++) - if (activeMotors[i] != m) - newMotors[j++] = activeMotors[i]; - activeMotors = newMotors; - } - - synchronized void shutdown() - { - // Shutdown all of the motors and prevent them from running - running = false; - for(JavaMotorRegulator m : activeMotors) - m.tachoPort.controlMotor(0, TachoMotorPort.FLOAT); - activeMotors = new JavaMotorRegulator[0]; - } - - - @Override - public void run() - { - running = true; - long now = System.currentTimeMillis(); - while(running) - { - long delta; - synchronized (this) - { - delta = System.currentTimeMillis() - now; - JavaMotorRegulator [] motors = activeMotors; - now += delta; - for(JavaMotorRegulator m : motors) - m.tachoCnt = m.tachoPort.getTachoCount() - m.zeroTachoCnt; - for(JavaMotorRegulator m : motors) - m.regulateMotor(delta); - for(JavaMotorRegulator m : motors) - m.tachoPort.controlMotor(m.power, m.mode); - } - Delay.msDelay(now + UPDATE_PERIOD - System.currentTimeMillis()); - } // end keep going loop - } - } - - - @Override - public void startSynchronization() - { - // TODO Auto-generated method stub - - } - - - @Override - public void endSynchronization(boolean b) - { - // TODO Auto-generated method stub - - } - - - @Override - public void synchronizeWith(MotorRegulator[] rl) - { - // TODO Auto-generated method stub - - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelMRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelMRegulatedMotor.java deleted file mode 100644 index 3c9092d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelMRegulatedMotor.java +++ /dev/null @@ -1,51 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a Mindsensors Glidewheel-M equipped PF motor.
    - * Note: These settings are for the "M" motor. This motor does not seem - * to like running slowly, or to use acceleration values less than around - * 500deg/s/s. Also tested with the "XL" motor which seems to work well other - * than some oscillation when holding. We may need different settings for - * the two. - * TODO: Find some way to make this work with an I term for hold - * TODO: Can probably be tuned better then this. - * - */ -public class MindsensorsGlideWheelMRegulatedMotor extends BaseRegulatedMotor -{ - static final float MOVE_P = 3.5f; - static final float MOVE_I = 0.01f; - static final float MOVE_D = 3f; - static final float HOLD_P = 2.5f; - static final float HOLD_I = 0f; - static final float HOLD_D = 0f; - static final int OFFSET = 0; - - private static final int MAX_SPEED = 405*360/60; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public MindsensorsGlideWheelMRegulatedMotor(TachoMotorPort port) - { - super(port, null, EV3SensorConstants.TYPE_MINITACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public MindsensorsGlideWheelMRegulatedMotor(Port port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelXLRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelXLRegulatedMotor.java deleted file mode 100644 index 86ef35a..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/MindsensorsGlideWheelXLRegulatedMotor.java +++ /dev/null @@ -1,47 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a Mindsensors Glidewheel-M equipped PF motor.
    - * Note: These settings are for the "XL" motor. - * TODO: Find some way to make this work with an I term for hold - * TODO: Can probably be tuned better then this. - * - */ -public class MindsensorsGlideWheelXLRegulatedMotor extends BaseRegulatedMotor -{ - static final float MOVE_P = 3.5f; - static final float MOVE_I = 0.01f; - static final float MOVE_D = 3f; - static final float HOLD_P = 2.5f; - static final float HOLD_I = 0f; - static final float HOLD_D = 0f; - static final int OFFSET = 0; - - private static final int MAX_SPEED = 220*360/60; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public MindsensorsGlideWheelXLRegulatedMotor(TachoMotorPort port) - { - super(port, null, EV3SensorConstants.TYPE_MINITACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public MindsensorsGlideWheelXLRegulatedMotor(Port port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/Motor.java b/ev3classes/src/main/java/lejos/hardware/motor/Motor.java deleted file mode 100644 index ca371e4..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/Motor.java +++ /dev/null @@ -1,49 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.BrickFinder; - -/** - * Motor class contains 3 instances of regulated motors. - *

    - * Example:

    - *

    - *   Motor.A.setSpeed(720);// 2 RPM
    - *   Motor.C.setSpeed(720);
    - *   Motor.A.forward();
    - *   Motor.C.forward();
    - *   Thread.sleep (1000);
    - *   Motor.A.stop();
    - *   Motor.C.stop();
    - *   Motor.A.rotateTo( 360);
    - *   Motor.A.rotate(-720,true);
    - *   while(Motor.A.isMoving() :Thread.yield();
    - *   int angle = Motor.A.getTachoCount(); // should be -360
    - *   LCD.drawInt(angle,0,0);
    - * 
    - * @author Roger Glassey/Andy Shaw - */ -public class Motor -{ - /** - * Motor A. - */ - public static final NXTRegulatedMotor A = new NXTRegulatedMotor(BrickFinder.getDefault().getPort("A")); - /** - * Motor B. - */ - public static final NXTRegulatedMotor B = new NXTRegulatedMotor(BrickFinder.getDefault().getPort("B")); - /** - * Motor C. - */ - public static final NXTRegulatedMotor C = new NXTRegulatedMotor(BrickFinder.getDefault().getPort("C")); - - /** - * Motor D. - */ - public static final NXTRegulatedMotor D = new NXTRegulatedMotor(BrickFinder.getDefault().getPort("D")); - - private Motor() { - // Motor class cannot be instantiated - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/MotorRegulator.java b/ev3classes/src/main/java/lejos/hardware/motor/MotorRegulator.java deleted file mode 100644 index a6df746..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/MotorRegulator.java +++ /dev/null @@ -1,148 +0,0 @@ -package lejos.hardware.motor; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; - -/** - * Interface for motor regulation - * regulate velocity; also stop motor at desired rotation angle. - - **/ -public interface MotorRegulator -{ - public static final int NO_LIMIT = 0x7fffffff; - - - /** - * Set the motion control parameters used by the regulator. - * @param typ The type of motor - * @param moveP The Proportional control value used while moving - * @param moveI The integral control parameter used while moving - * @param moveD The differential control parameter used while moving - * @param holdP The Proportional control value used while holding position - * @param holdI The integral control value used while holding position - * @param holdD The differential control value used while holding position - * @param offset Motor PWM offset value range 0-10000. - */ - public void setControlParamaters(int typ, float moveP, float moveI, float moveD, float holdP, float holdI, float holdD, int offset); - /** - * Get the current hardware tachometer reading for the motor, - * @return hardware reading - */ - public int getTachoCount(); - - /** - * Reset the tachometer base value, after this call the tachometer will return - * zero for the current position. Note that any in progress movements will be - * aborted. - */ - public void resetTachoCount(); - - /** - * Return true if the motor is currently active - * @return True if the motor is moving. - */ - public boolean isMoving(); - - /** - * Return the current velocity (in degrees/second) that the motor is currently - * running at. Note that this value may be supplied from the internal - * control model not from actually measuring the rotation speed. If the regulator - * is functioning correctly this will closely match the actual velocity - * @return velocity - */ - public float getCurrentVelocity(); - - /** - * Set the stall detection parameters. The motor will be declared as - * stalled if the error in the motor position exceeds the specified value for - * longer than the given time. - * @param error - * @param time - */ - public void setStallThreshold(int error, int time); - - /** - * return the regulations models current position. - * @return the models current position - */ - public float getPosition(); - - /** - * Initiate a new move and optionally wait for it to complete. - * If some other move is currently executing then ensure that this move - * is terminated correctly and then start the new move operation. - * @param speed - * @param acceleration - * @param limit - * @param hold - * @param waitComplete - */ - public void newMove(float speed, int acceleration, int limit, boolean hold, boolean waitComplete); - - /** - * The target speed has been changed. Reflect this change in the - * regulator. - * @param newSpeed new target speed. - */ - public void adjustSpeed(float newSpeed); - - /** - * The target acceleration has been changed. Updated the regulator. - * @param newAcc - */ - public void adjustAcceleration(int newAcc); - - /** - * Wait until the current movement operation is complete (this can include - * the motor stalling). - */ - public void waitComplete(); - - /** - * Add a motor listener. Move operations will be reported to this object. - * @param motor - * @param listener - */ - public void addListener(RegulatedMotor motor, RegulatedMotorListener listener); - - public RegulatedMotorListener removeListener(); - - - /** - * Return the angle that this Motor is rotating to. - * @return angle in degrees - */ - public int getLimitAngle(); - - /** - * Return true if the motor is currently stalled. - * @return true if the motor is stalled, else false - */ - public boolean isStalled(); - - /** - * Begin a set of synchronized motor operations - */ - public void startSynchronization(); - - /** - * Complete a set of synchronized motor operations. - */ - public void endSynchronization(boolean b); - - /** - * Specify a set of motors that should be kept in synchronization with this one. - * The synchronization mechanism simply ensures that operations between a startSynchronization - * call and an endSynchronization call will all be executed at the same time (when the - * endSynchronization method is called). This is all that is needed to ensure that motors - * will operate in a synchronized fashion. The start/end methods can also be used to ensure - * that reads of the motor state will also be consistent. - * @param rl an array of motors to synchronize with. - */ - public void synchronizeWith(MotorRegulator[] rl); - - -} - - diff --git a/ev3classes/src/main/java/lejos/hardware/motor/NXTRegulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/NXTRegulatedMotor.java deleted file mode 100644 index 5f710f3..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/NXTRegulatedMotor.java +++ /dev/null @@ -1,43 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a Lego NXT motor. - * - */ -public class NXTRegulatedMotor extends BaseRegulatedMotor -{ - static final float MOVE_P = 4f; - static final float MOVE_I = 0.04f; - static final float MOVE_D = 10f; - static final float HOLD_P = 2f; - static final float HOLD_I = 0.02f; - static final float HOLD_D = 8f; - static final int OFFSET = 0; - private static final int MAX_SPEED = 170*360/60; - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public NXTRegulatedMotor(TachoMotorPort port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - /** - * Use this constructor to assign a variable of type motor connected to a particular port. - * @param port to which this motor is connected - */ - public NXTRegulatedMotor(Port port) - { - super(port, null, EV3SensorConstants.TYPE_NEWTACHO, MOVE_P, MOVE_I, MOVE_D, - HOLD_P, HOLD_I, HOLD_D, OFFSET, MAX_SPEED); - } - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/RCXMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/RCXMotor.java deleted file mode 100644 index 8c72989..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/RCXMotor.java +++ /dev/null @@ -1,24 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.motor.BasicMotor; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.Port; - -/** - * Abstraction for an RCX motor. - * - */ -public class RCXMotor extends BasicMotor { - - public RCXMotor(BasicMotorPort port) - { - this.port = port; - } - - public RCXMotor(Port port) - { - this(port.open(BasicMotorPort.class)); - releaseOnClose(this.port); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/Tachometer.java b/ev3classes/src/main/java/lejos/hardware/motor/Tachometer.java deleted file mode 100644 index fae78eb..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/Tachometer.java +++ /dev/null @@ -1,17 +0,0 @@ -package lejos.hardware.motor; - -/** - * Abstraction for the tachometer built into NXT motors. - * - * @author Lawrie Griffiths - * - *

    WARNING: THIS CLASS IS SHARED BETWEEN THE classes AND pccomms PROJECTS. - * DO NOT EDIT THE VERSION IN pccomms AS IT WILL BE OVERWRITTEN WHEN THE PROJECT IS BUILT. - */ -public interface Tachometer { - - public int getTachoCount(); - - public void resetTachoCount(); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/UnregulatedMotor.java b/ev3classes/src/main/java/lejos/hardware/motor/UnregulatedMotor.java deleted file mode 100644 index 3726b4e..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/UnregulatedMotor.java +++ /dev/null @@ -1,70 +0,0 @@ -package lejos.hardware.motor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.robotics.Encoder; -import lejos.robotics.EncoderMotor; - -/** - * Abstraction for an NXT motor with no speed regulation. - * - */ -public class UnregulatedMotor extends BasicMotor implements EncoderMotor { - protected Encoder encoderPort; - - /** - * Create an instance of a NXTMotor using the specified motor port and - * PWM operating mode. - * @param port The motor port that the motor will be attached to. - * @param PWMMode see {@link lejos.hardware.port.BasicMotorPort#PWM_FLOAT} and see {@link lejos.hardware.port.BasicMotorPort#PWM_BRAKE} - */ - public UnregulatedMotor(Port port, int PWMMode) - { - this(port.open(TachoMotorPort.class), PWMMode); - releaseOnClose(this.port); - } - - /** - * Create an instance of a NXTMotor using the specified motor port the - * PWM operating mode will be PWM_BREAK {@link lejos.hardware.port.BasicMotorPort#PWM_BRAKE} - * @param port The motor port that the motor will be attached to. - */ - public UnregulatedMotor(Port port) - { - this(port, TachoMotorPort.PWM_BRAKE); - } - - /** - * Create an instance of a NXTMotor using the specified motor port and - * PWM operating mode. - * @param mport The motor port that the motor will be attached to. - * @param PWMMode see {@link lejos.hardware.port.BasicMotorPort#PWM_FLOAT} and see {@link lejos.hardware.port.BasicMotorPort#PWM_BRAKE} - */ - public UnregulatedMotor(TachoMotorPort mport, int PWMMode) - { - this.port = mport; - // We use extra var to avoid cost of a cast check later - encoderPort = mport; - mport.setPWMMode(PWMMode); - } - - /** - * Create an instance of a NXTMotor using the specified motor port the - * PWM operating mode will be PWM_BREAK {@link lejos.hardware.port.BasicMotorPort#PWM_BRAKE} - * @param port The motor port that the motor will be attached to. - */ - public UnregulatedMotor(TachoMotorPort port) - { - this(port, TachoMotorPort.PWM_BRAKE); - } - - public int getTachoCount() - { - return encoderPort.getTachoCount(); - } - - public void resetTachoCount() - { - encoderPort.resetTachoCount(); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/motor/package-info.java b/ev3classes/src/main/java/lejos/hardware/motor/package-info.java deleted file mode 100644 index b884a86..0000000 --- a/ev3classes/src/main/java/lejos/hardware/motor/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Access to the motors that the EV3 supports. - * - * Motors supported by specific controllers are in lejos.hardwae.device. - */ -package lejos.hardware.motor; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/package-info.java b/ev3classes/src/main/java/lejos/hardware/package-info.java deleted file mode 100644 index 6a3c33b..0000000 --- a/ev3classes/src/main/java/lejos/hardware/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * EV3 hardware support - */ -package lejos.hardware; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/port/AnalogPort.java b/ev3classes/src/main/java/lejos/hardware/port/AnalogPort.java deleted file mode 100644 index cc74ae8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/AnalogPort.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.hardware.port; - -/** - * An abstraction for a port that supports Analog/Digital sensors. - * - * @author Lawrie Griffiths/Andy. - * - */ -public interface AnalogPort extends IOPort, BasicSensorPort { - /** - * return the voltage present on pin 6 of the sensor port - * @return voltage reading - */ - public float getPin6(); - - /** - * return the voltage present on pin 1 of the sensor port - * @return voltage reading - */ - public float getPin1(); - - /** - * Return a series of results obtained from the sensor. - * This is currently only used for the NXT color sensor - * @param vals Place to store the values - * @param offset Offset into the above array to start storing - * @param length number of values to read - */ - public void getFloats(float [] vals, int offset, int length); -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/BasicMotorPort.java b/ev3classes/src/main/java/lejos/hardware/port/BasicMotorPort.java deleted file mode 100644 index 7bda2d0..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/BasicMotorPort.java +++ /dev/null @@ -1,29 +0,0 @@ -package lejos.hardware.port; - -/** - * An abstraction for a motor port that supports RCX - * type motors, but not NXT motors with tachometers. - * - * @author Lawrie Griffiths. - * - */ -public interface BasicMotorPort extends IOPort { - /** PWM Mode. Motor is not driven during off phase of PWM */ - static public final int PWM_FLOAT = 0; - /** PWM Mode. Motor is driven during off phase of PWM */ - static public final int PWM_BRAKE = 1; - /** Motor is running forward */ - public final static int FORWARD = 1; - /** Motor is running backwards */ - public final static int BACKWARD = 2; - /** Motor is stopped (PWM drive still applied) */ - public final static int STOP = 3; - /** Motor is floating (no PWM drive) */ - public final static int FLOAT = 4; - /** Maximum power setting = 100% */ - public final static int MAX_POWER = 100; - - public void controlMotor(int power, int mode); - - public void setPWMMode(int mode); -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/BasicSensorPort.java b/ev3classes/src/main/java/lejos/hardware/port/BasicSensorPort.java deleted file mode 100644 index fb72268..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/BasicSensorPort.java +++ /dev/null @@ -1,48 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.sensor.SensorConstants; - -/** - * An abstraction for a sensor port that supports - * setting and retrieving types and modes of sensors. - * - * @author Lawrie Griffiths. - * - */ -public interface BasicSensorPort extends SensorConstants { - - /** - * Get the current operating mode of the sensor - * @return the current mode - */ - public int getMode(); - - /** - * Get the current type setting. Note that types are typically used to - * control the operation of Legacy and i2c sensors. They are normally not - * used for EV3 sensors. - * @return the current sensor type - */ - public int getType(); - - /** - * Set the current operating mode for the sensor attached to the port. - * @param mode the new mode - * @return true if the mode has been accepted - */ - public boolean setMode(int mode); - - /** - * Set the operating type for the attached sensor. Normally type setting is - * only used with legacy sensors and for i2c devices (to set the speed and - * operating voltage). It is not normally used with EV3 sensors. - * @param type - * @return true if type accepted - */ - public boolean setType(int type); - - @Deprecated - public boolean setTypeAndMode(int type, int mode); - -} - diff --git a/ev3classes/src/main/java/lejos/hardware/port/ConfigurationPort.java b/ev3classes/src/main/java/lejos/hardware/port/ConfigurationPort.java deleted file mode 100644 index 82809d8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/ConfigurationPort.java +++ /dev/null @@ -1,22 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.sensor.EV3SensorConstants; - -public interface ConfigurationPort extends IOPort, EV3SensorConstants -{ - /** - * Get the type classification for the port. If a sensor is attached to the port - * this will identify the connection type (UART/IIC/Dumb/Output etc.) - * @return The type of the port. - */ - public int getPortType(); - - /** - * This function returns information on the sensor/motor that is attached to the - * specified port. Note that only very basic sensor identification information - * may be available for some sensor types. It may be necessary to actually open the - * sensor to allow it to be identified in further detail. - * @return the sensor type - */ - public int getDeviceType(); -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/I2CException.java b/ev3classes/src/main/java/lejos/hardware/port/I2CException.java deleted file mode 100644 index 47e8f26..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/I2CException.java +++ /dev/null @@ -1,25 +0,0 @@ -package lejos.hardware.port; - -public class I2CException extends PortException { - - private static final long serialVersionUID = -1429576101467185066L; - - public I2CException() - { - } - - public I2CException(String message) - { - super (message); - } - - public I2CException(Throwable cause) - { - super (cause); - } - - public I2CException(String message, Throwable cause) - { - super (message, cause); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/I2CPort.java b/ev3classes/src/main/java/lejos/hardware/port/I2CPort.java deleted file mode 100644 index 7080656..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/I2CPort.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Abstraction for a port that supports I2C sensors. - * - * @author Lawrie Griffiths - * - */ -public interface I2CPort extends IOPort, BasicSensorPort { - /** Maximum read/write request length */ - public static final int MAX_IO = EV3SensorConstants.IIC_DATA_LENGTH; - - /** - * High level i2c interface. Perform a complete i2c transaction and return - * the results. Writes the specified data to the device and then reads the - * requested bytes from it. - * @param deviceAddress The I2C device address. - * @param writeBuf The buffer containing data to be written to the device. - * @param writeOffset The offset of the data within the write buffer - * @param writeLen The number of bytes to write. - * @param readBuf The buffer to use for the transaction results - * @param readOffset Location to write the results to - * @param readLen The length of the read - */ - public void i2cTransaction(int deviceAddress, byte[]writeBuf, - int writeOffset, int writeLen, byte[] readBuf, int readOffset, - int readLen); -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/IOPort.java b/ev3classes/src/main/java/lejos/hardware/port/IOPort.java deleted file mode 100644 index 2350113..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/IOPort.java +++ /dev/null @@ -1,32 +0,0 @@ -package lejos.hardware.port; - -import java.io.Closeable; - -/** - * Basic interface for EV3 sensor ports. - * TODO: Need to cleanup the setting of modes etc. should probably become - * part of the open, with some sort of name/value string pairs. - * @author andy - * - */ -public interface IOPort extends Closeable { - - /** - * Close the port, the port can not be used after this call. - */ - public void close(); - - /** - * Return the string representing this port - * @return the port name - */ - public String getName(); - - /** - * Set the port pins up ready for use. - * @param mode The EV3 pin mode - * @return true if the operation succeeds false if it fails - */ - public boolean setPinMode(int mode); - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/port/LegacySensorPort.java b/ev3classes/src/main/java/lejos/hardware/port/LegacySensorPort.java deleted file mode 100644 index 9242c76..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/LegacySensorPort.java +++ /dev/null @@ -1,14 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.port.AnalogPort; - -/** - * Abstraction for a port that supports legacy RCX sensors. - * - * @author Lawrie Griffiths. - * - */ -public interface LegacySensorPort extends AnalogPort { - public void activate(); - public void passivate(); -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/MotorPort.java b/ev3classes/src/main/java/lejos/hardware/port/MotorPort.java deleted file mode 100644 index b0360b6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/MotorPort.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.BrickFinder; - -/** - * - * Abstraction for an EV3 output port. - * - * TODO: Sort out a better way to do this, or least clean up the magic numbers. - * - */ -public interface MotorPort { - - /** - * MotorPort A. - */ - public static final Port A = BrickFinder.getDefault().getPort("A"); - - /** - * MotorPort B. - */ - public static final Port B = BrickFinder.getDefault().getPort("B"); - - /** - * MotorPort C. - */ - public static final Port C = BrickFinder.getDefault().getPort("C"); - - /** - * MotorPort D. - */ - public static final Port D = BrickFinder.getDefault().getPort("D"); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/Port.java b/ev3classes/src/main/java/lejos/hardware/port/Port.java deleted file mode 100644 index f652a3f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/Port.java +++ /dev/null @@ -1,24 +0,0 @@ -package lejos.hardware.port; - -/** - * Interface that provides a binding between a physical port and the different - * types of sensor interfaces that can be used with it - * @author andy - * - */ -public interface Port -{ - /** - * return the string name used to reference this physical port - * @return a string representation of the port - */ - public String getName(); - - /** - * Obtain access to a class that can be used to talk to the port hardware - * @param portclass the required port interface - * @return a class that implements the requested interface - */ - public T open(Class portclass); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/PortException.java b/ev3classes/src/main/java/lejos/hardware/port/PortException.java deleted file mode 100644 index c68d733..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/PortException.java +++ /dev/null @@ -1,31 +0,0 @@ -package lejos.hardware.port; - -/** - * Exception thrown when errors are detected accessing a port. - * - * @author Lawrie Griffiths - * - */ -public class PortException extends RuntimeException -{ - private static final long serialVersionUID = 3469971731990732986L; - - public PortException() - { - } - - public PortException(String message) - { - super (message); - } - - public PortException(Throwable cause) - { - super (cause); - } - - public PortException(String message, Throwable cause) - { - super (message, cause); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/SensorPort.java b/ev3classes/src/main/java/lejos/hardware/port/SensorPort.java deleted file mode 100644 index 23cd0d8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/SensorPort.java +++ /dev/null @@ -1,16 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.BrickFinder; - -/** - * Basic interface for EV3 sensor ports. - * @author andy - * - */ -public interface SensorPort { - public static final Port S1 = BrickFinder.getDefault().getPort("S1"); - public static final Port S2 = BrickFinder.getDefault().getPort("S2"); - public static final Port S3 = BrickFinder.getDefault().getPort("S3"); - public static final Port S4 = BrickFinder.getDefault().getPort("S4"); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/TachoMotorPort.java b/ev3classes/src/main/java/lejos/hardware/port/TachoMotorPort.java deleted file mode 100644 index 5d1a431..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/TachoMotorPort.java +++ /dev/null @@ -1,18 +0,0 @@ -package lejos.hardware.port; - -import lejos.hardware.motor.MotorRegulator; -import lejos.robotics.Encoder; - -/** - * Abstraction for a motor port that supports NXT motors with tachometers. - * - * @author Lawrie Griffiths - * - */ -public interface TachoMotorPort extends BasicMotorPort, Encoder { - /** - * Return the motor regulator associated with this motor port. - * @return the motor regulator for this port. - */ - public MotorRegulator getRegulator(); -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/port/UARTPort.java b/ev3classes/src/main/java/lejos/hardware/port/UARTPort.java deleted file mode 100644 index 0f25539..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/UARTPort.java +++ /dev/null @@ -1,103 +0,0 @@ -package lejos.hardware.port; - - -public interface UARTPort extends IOPort, BasicSensorPort -{ - public static final int UART_RAW_MODE = -1; - - /** - * read a single byte from the device - * @return the byte value - */ - public byte getByte(); - - /** - * read a number of bytes from the device - * @param vals byte array to accept the data - * @param offset offset at which to store the data - * @param len number of bytes to read - */ - public void getBytes(byte [] vals, int offset, int len); - - /** - * read a single short from the device. - * @return the short value - */ - public int getShort(); - - /** - * read a number of shorts from the device - * @param vals short array to accept the data - * @param offset offset at which to store the data - * @param len number of shorts to read - */ - public void getShorts(short [] vals, int offset, int len); - - /** - * Get the string name of the specified mode.

    - * TODO: Make other mode data available. - * @param mode mode to lookup - * @return String version of the mode name - */ - public String getModeName(int mode); - - /** - * Return the current sensor reading to a string. - */ - public String toString(); - - /** - * Initialise the attached sensor and set it to the required operating mode.
    - * Note: This method is not normally needed as the sensor will be initialised - * when it is opened. However it may be of use if the sensor needs to be reset - * or in other cases. - * @param mode target mode - * @return true if ok false if error - */ - boolean initialiseSensor(int mode); - - /** - * Reset the attached sensor. Following this the sensor must be initialised - * before it can be used. - */ - void resetSensor(); - - /** - * Write bytes to the sensor - * @param buffer bytes to be written - * @param offset offset to the start of the write - * @param len length of the write - * @return number of bytes written - */ - int write(byte[] buffer, int offset, int len); - - /** - * Read bytes from the uart port. If no bytes are available return 0.

    - * Note: The port must have been set into RAW mode to use this method. - * @param buffer The buffer to store the read bytes - * @param offset The offset at which to start storing the bytes - * @param len The maximum number of bytes to read - * @return The actual number of bytes read - */ - public int rawRead(byte[] buffer, int offset, int len); - - /** - * Attempt to write a series of bytes to the uart port. This call - * is non-blocking if there is no space in the write buffer a count - * of 0 is returned.

    - * Note: The port must have been set into RAW mode before attempting - * to use the method. - * @param buffer The buffer containing the bytes to write - * @param offset The offset of the first byte - * @param len The number of bytes to attempt to write - * @return The actual number of bytes written - */ - public int rawWrite(byte[] buffer, int offset, int len); - - /** - * Set the bit rate of the port when operating in RAW mode. - * @param bitRate The new bit rate - */ - public void setBitRate(int bitRate); - -} diff --git a/ev3classes/src/main/java/lejos/hardware/port/package-info.java b/ev3classes/src/main/java/lejos/hardware/port/package-info.java deleted file mode 100644 index d4081a9..0000000 --- a/ev3classes/src/main/java/lejos/hardware/port/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Access to EV3 ports - */ -package lejos.hardware.port; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/AnalogSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/AnalogSensor.java deleted file mode 100644 index 2ecca3d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/AnalogSensor.java +++ /dev/null @@ -1,94 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.utility.Delay; - -/** - * Base class for analog sensor drivers - * @author andy - * - */ -public class AnalogSensor extends BaseSensor implements SensorConstants -{ - protected AnalogPort port; - protected int currentType = -1; - - public AnalogSensor(AnalogPort p) - { - this.port = p; - } - - public AnalogSensor(Port p, int type, int mode) - { - this(p.open(AnalogPort.class)); - if (!port.setTypeAndMode(type, mode)) - { - port.close(); - throw new IllegalArgumentException("Invalid sensor mode"); - } - releaseOnClose(this.port); - } - - public AnalogSensor(Port p) - { - this(p, TYPE_CUSTOM, MODE_RAW); - } - - - - /** - * 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; - } - - /** - * Return the equivalent NXT RAW sensor reading to the given voltage - * @param val ADC voltage - * @return The reading that would be returned on the NXT - */ - protected float NXTRawValue(float val) - { - return val*SensorConstants.NXT_ADC_RES/EV3SensorConstants.ADC_REF; - } - - /** - * Return the equivalent NXT RAW sensor reading to the given voltage - * @param val ADC voltage - * @return The reading that would be returned on the NXT - */ - protected int NXTRawIntValue(float val) - { - return (int)(NXTRawValue(val)+0.5); - } - - - /** - * 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) - { - if (!port.setType(newType)) - throw new IllegalArgumentException("Invalid sensor mode"); - currentType = newType; - Delay.msDelay(switchDelay); - } - } - //TODO: Add a switchPinMode or whatever method for use by EV3 sensors. At the moment - // there are no EV3 analog sensors that are controlled by pin settings. - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/BaseSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/BaseSensor.java deleted file mode 100644 index 43d9c0f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/BaseSensor.java +++ /dev/null @@ -1,125 +0,0 @@ -package lejos.hardware.sensor; - -import java.util.ArrayList; - -import lejos.hardware.Device; - - -public class BaseSensor extends Device implements SensorModes -{ - protected int currentMode = 0; - protected SensorMode[] modes; - ArrayList modeList; - - /** - * Define the set of modes to be made available for this sensor. - * @param m An array containing a list of modes - */ - protected void setModes(SensorMode[] m) - { - modes = m; - // force the list to be rebuilt - modeList = null; - currentMode = 0; - } - - @Override - public ArrayList getAvailableModes() - { - if (modeList == null) - { - modeList = new ArrayList(modes.length); - if (modes != null) - for(SensorMode m : modes) - modeList.add(m.getName()); - } - return modeList; - } - - @Override - public SensorMode getMode(int mode) - { - if (mode < 0) - throw new IllegalArgumentException("Invalid mode " + mode); - if (modes == null || mode >= modes.length) - return null; - return modes[mode]; - } - - @Override - public SensorMode getMode(String modeName) - { - // TODO: I'm sure there is a better way to do this, but it is late! - int i = 0; - for(String s : getAvailableModes()) - { - if (s.equals(modeName)) - return modes[i]; - i++; - } - throw new IllegalArgumentException("No such mode " + modeName); - } - - private boolean isValid(int mode) { - if (mode < 0 || modes == null || mode >= modes.length) return false; - return true; - } - - private int getIndex(String modeName) { - int i = 0; - for(String s : getAvailableModes()) - { - if (s.equals(modeName)) - return i; - i++; - } - return -1; - } - - @Override - public String getName() { - return modes[currentMode].getName(); - } - - @Override - public int sampleSize() { - return modes[currentMode].sampleSize(); - } - - @Override - public void fetchSample(float[] sample, int offset) { - modes[currentMode].fetchSample(sample, offset); - } - - @Override - public void setCurrentMode(int mode) { - if (!isValid(mode)) { - throw new IllegalArgumentException("Invalid mode " + mode); - } - else { - currentMode = mode; - } - } - - @Override - public void setCurrentMode(String modeName) { - int mode = getIndex(modeName); - if (mode==-1) { - throw new IllegalArgumentException("Invalid mode " + modeName); - } - else { - currentMode = mode; - } - } - - @Override - public int getCurrentMode() { - return currentMode; - } - - @Override - public int getModeCount() { - return modes.length; - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/CodeTemplate.java b/ev3classes/src/main/java/lejos/hardware/sensor/CodeTemplate.java deleted file mode 100644 index 5d4da17..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/CodeTemplate.java +++ /dev/null @@ -1,132 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.robotics.SampleProvider; - -/** - * Sensor name
    - * Description - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Some {@link #getSomeMode() }
    - * - * - *

    - * Sensor configuration
    - * Description of default sensor configuration (when that matters). Description - * of available methods for configuration. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Your name - * - */ -public class CodeTemplate extends UARTSensor { - - /** - * Constructor using a unopened port - * - * @param port - */ - public CodeTemplate(Port port) { - super(port); - init(); - } - - /** - * Constructor using a opened and configured port - * - * @param port - */ - public CodeTemplate(UARTPort port) { - super(port); - init(); - } - - /** - * Configures the sensor for first use and registers the supported modes - * - */ - protected void init() { - setModes(new SensorMode[] { new SomeMode() }); - } - - /** - * Sensor name, mode
    - * Mode description - * - *

    - * Size and content of the sample
    - * The sample contains # elements. Each element gives Something (in some - * unit). - * - *

    - * Configuration
    - * The sensor is configured for.... . Currently there are no configurable - * settings. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getSomeMode() { - return getMode(0); - - } - - private class SomeMode implements SensorMode { - - @Override - public int sampleSize() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void fetchSample(float[] sample, int offset) { - // TODO Auto-generated method stub - - } - - @Override - public String getName() { - // TODO Auto-generated method stub - return "Some"; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/CruizcoreGyro.java b/ev3classes/src/main/java/lejos/hardware/sensor/CruizcoreGyro.java deleted file mode 100644 index 7416c12..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/CruizcoreGyro.java +++ /dev/null @@ -1,307 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - -/** - * Micro Infinity Cruizcore XG1300L
    - * The XG1300L is a fully self-contained digital MEMS gyroscope and - * accelerometer. - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * Rate - * - * - * - * - * - * - * Angle - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    AccelerationMeasures linear acceleration over three axes {@link #getAccelerationMode() }
    RateMeasures rate of turn over the Z-axis {@link #getRateMode() }
    Measures angle over the Z-axis {@link #getAngleMode() }
    - * - * - * - *

    - * - * See - * Sensor datasheet - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Daniele Benedettelli - * - */ -public class CruizcoreGyro extends I2CSensor { - - /* - * Documentation can be obtained here: - * http://www.minfinity.com/Manual/CruizCore_XG1300L_User_Manual.pdf The - * documentation and the conversion in the NXC sample code indicate, that - * 16bit signed little endian values are returned. - */ - - private byte[] inBuf = new byte[11]; - private static final byte GYRO_ADDRESS = 0x02; - - // values returned are signed short integers multiplied by 100 - private static final byte ANGLE = 0x42; // 0x43 (2 Bytes) - - private static final byte RATE = 0x44; // 0x45 (2 Bytes) - - private static final byte ACCEL_X = 0x46; // 0x47 (2 Bytes) - // private static - // final - // byte ACCEL_Y = - // 0x48; - // // 0x49 (2 Bytes) - // private static - // final - // byte ACCEL_Z = - // 0x4A; - // // 0x4B (2 Bytes) - - // the commands are issued by just reading these registers - - private static final byte RESET = 0x60; - - private static final byte SELECT_SCALE = 0x61; - - private float scale; - - /** - * Instantiates a new Cruizcore Gyro sensor. - * - * @param port - * the port the sensor is attached to - */ - public CruizcoreGyro(I2CPort port) { - super(port, GYRO_ADDRESS); - init(); - } - - public CruizcoreGyro(Port port) { - super(port, GYRO_ADDRESS); - init(); - } - - protected void init() { - setAccScale2G(); - setModes(new SensorMode[] { new AccelerationMode(), new RateMode(), new AngleMode() }); - } - - /** - * Sets the acc scale. - * - * @param sf - * the scale factor: 0 for +/- 2G, 1 for +/- 4G, 2 for +/- 8g - * @throws IllegalArgumentException - * if the parameter is neither 0, 1, or 2. - */ - public void setAccScale(int sf) { - if (sf < 0 || sf > 2) - throw new IllegalArgumentException(); - // TODO we write one byte too many (the zero). - // The driver should perform a zero length write to register SELECT_SCALE + sf. - sendData(SELECT_SCALE + sf, (byte) 0); - scale = 0.00981f * (1 << sf); - } - - /** - * Sets the acceleration scale factor to 2G. - */ - public void setAccScale2G() { - setAccScale((byte) 0); - } - - /** - * Sets the acceleration scale factor to 4G. - */ - public void setAccScale4G() { - setAccScale((byte) 1); - } - - /** - * Sets the acceleration scale factor to 8G. - */ - public void setAccScale8G() { - setAccScale((byte) 2); - } - - /** - * Resets the accumulated angle (heading). - * - */ - public void reset() { - sendData(RESET, (byte) 0); - Delay.msDelay(750); - } - - /** - * Cruizcore XG1300L, Acceleration mode
    - * Measures linear acceleration over three axes - * - *

    - * Size and content of the sample
    - * The sample contains 3 elements. Each element gives linear acceleration - * (in metres/second^2). Axis order in sample is X, Y, Z. - * - *

    - * Configuration
    - * The sensor can be configured for range using the setAccScale#G() methods - * of the sensor class. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See - * Sensor datasheet - */ - public SensorMode getAccelerationMode() { - return getMode(0); - } - - private class AccelerationMode implements SensorMode { - - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(ACCEL_X, inBuf, 6); - sample[0 + offset] = EndianTools.decodeShortLE(inBuf, 2) * scale; - sample[1 + offset] = EndianTools.decodeShortLE(inBuf, 0) * scale; - sample[2 + offset] = -EndianTools.decodeShortLE(inBuf, 4) * scale; - } - - @Override - public String getName() { - return "Acceleration"; - } - } - - /** - * Cruizcore XG1300L, Acceleration mode
    - * Measures rate of turn over the Z-axis - * - *

    - * Size and content of the sample
    - * The sample contains one element, the rate of turn (in degrees / second) - * over the Z-axis. - * - *

    - * Configuration
    - * There are no configurable parameters. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See - * Sensor datasheet - */ - public SensorMode getRateMode() { - return getMode(1); - } - - private class RateMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(RATE, inBuf, 2); - sample[offset] = -EndianTools.decodeShortLE(inBuf, 0) / 100f; - } - - @Override - public String getName() { - return "Rate"; - } - } - - /** - * Cruizcore XG1300L, Angle mode
    - * Measures angle over the Z-axis - * - *

    - * Size and content of the sample
    - * The sample contains one element, the accumulated angle (in degrees). . - * - *

    - * Configuration
    - * The accumulated angle can be reset to zero using the reset() method of - * the sensor class. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See - * Sensor datasheet - */ - public SensorMode getAngleMode() { - return getMode(2); - } - - private class AngleMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(ANGLE, inBuf, 2); - sample[offset] = 360 - EndianTools.decodeShortLE(inBuf, 0) / 100f; - } - - @Override - public String getName() { - return "Angle"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterCompassSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterCompassSensor.java deleted file mode 100644 index b9ea22b..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterCompassSensor.java +++ /dev/null @@ -1,358 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - -/** - * Dexter Industries dCompass sensor
    - * A three axis magnetometer - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    MagneticMeasures the strength of the magnetic field over three axes {@link #getMagneticMode() }
    - * - * - *

    - * Sensor configuration
    - * Range can be set Using getRanges() and setRange methods. Internal update - * frequency of the sensor can be set using getRates and setRate methods. - * - *

    - * - * See - * Sensor datasheet - * See Sensor Product - * page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Aswin Bouwmeester - * - */ -public class DexterCompassSensor extends I2CSensor implements SensorModes{ - - // sensor configuration - static final int MODE_NORMAL = 0; - static final int MODE_POSITIVE_BIAS = 1; - static final int MODE_NEGATIVE_BIAS = 2; - private final static float[] RATES = { 0.75f, 1.5f, 3, 7.5f, 15, 30, 75 }; - private final static int[] RANGEMULTIPLIER = { 1370, 1090, 820, 660, 440, 390, 330, 230 }; - private final static float[] RANGES = { 0.88f, 1.3f, 1.9f, 2.5f, 4, 4.7f, 5.6f, 8.1f }; - static final int CONTINUOUS = 0; - static final int SINGLE = 1; - static final int IDLE = 2; - - // default configuration - int measurementMode = MODE_NORMAL; - int range = 6; - int rate = 5; - int operatingMode = CONTINUOUS; - - // sensor register adresses - private static final int I2C_ADDRESS = 0x3C; - protected static final int REG_CONFIG = 0x00; - protected static final int REG_MAGNETO = 0x03; - protected static final int REG_STATUS = 0x09; - - // local variables for common use - float[] raw = new float[3]; - float[] dummy = new float[3]; - byte[] buf = new byte[6]; - private float multiplier; - - /** - * Constructor for the driver. - * - * @param port - */ - public DexterCompassSensor(I2CPort port) { - super(port, I2C_ADDRESS); - init(); - } - - public DexterCompassSensor(Port port) { - super(port, I2C_ADDRESS, TYPE_LOWSPEED); - init(); - } - - /** - * Dexter Industries dCompass sensor, magnetic mode
    - * Measures the strength of the magnetic field over three axes - * - *

    - * Size and content of the sample
    - * The sample contains 3 elements. Each element gives the strength of the - * magnetic field (in Gueass). Axis order is X, Y, Z. - * - *

    - * Configuration
    - * By default the sensor is configured for a range of 5.6 Gauss and an - * update frequency of 30 Hertz.
    - * The sensor can be tested using the test method. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See - * Sensor datasheet - */ - public SampleProvider getMagneticMode() { - return getMode(0); - } - - protected void init() { - setModes(new SensorMode[] { new MagneticMode() }); - configureSensor(); - } - - /** - * Sets the configuration registers of the sensor according to the current - * settings - */ - private void configureSensor() { - - buf[0] = (byte) ((3 << 5) | (rate << 2) | measurementMode); - buf[1] = (byte) (range << 5); - buf[2] = (byte) (operatingMode); - - sendData(REG_CONFIG, buf, 3); - - Delay.msDelay(6); - - multiplier = 1.0f / RANGEMULTIPLIER[range]; - // first measurement after configuration is not yet configured properly; - Delay.msDelay(6); - getMode(0).fetchSample(dummy, 0); - } - - /** - * fetches measurement in single measurement mode - * - * @param ret - */ - private void fetchSingleMeasurementMode(float[] ret, int offset) { - buf[0] = 0x01; - sendData(0x02, buf[0]); - Delay.msDelay(6); - fetch(ret, offset); - } - - /** - * @return Returns the measurement mode of the sensor (normal, positive bias - * or negative bias). - *

    - * positive and negative bias mode should only be used for testing - * the sensor. - */ - protected int getMeasurementMode() { - return measurementMode; - } - - /** - * @return The operating mode of the sensor (single measurement, continuous - * or Idle) - */ - protected int getOperatingMode() { - return operatingMode; - } - - /** - * @return The dynamic range of the sensor. - */ - public float getMaximumRange() { - return RANGES[range]; - } - - /** - * Reads the new data ready bit of the status register of the sensor. - * - * @return True if new data available - */ - protected boolean newDataAvailable() { - getData(REG_STATUS, buf, 1); - return ((buf[0] & 0x01) != 0); - } - - /** - * @param measurementMode - * Sets the measurement mode of the sensor. - */ - protected void setMeasurementMode(int measurementMode) { - this.measurementMode = measurementMode; - configureSensor(); - } - - /** - * Sets the operating mode of the sensor - * - * @param operatingMode - * Continuous is normal mode of operation - *

    - * SingleMeasurement can be used to conserve energy or to - * increase maximum measurement rate - *

    - * Idle is to stop the sensor and conserve energy - */ - protected void setOperatingMode(int operatingMode) { - this.operatingMode = operatingMode; - configureSensor(); - } - - /** - * Sets the dynamic range of the sensor (1.3 Gauss is default). - * - * @param range - */ - public void setRange(int range) { - this.range = (byte) range; - configureSensor(); - } - - /** - * Self-test routine of the sensor. - * - * @return An array of boolean values. A true indicates the sensor axis is - * working properly. - */ - public boolean[] test() { - boolean[] ret = new boolean[3]; - - // store current settings; - int currentMode = measurementMode; - int currentRange = range; - int currentOperatingMode = operatingMode; - - // modify settings for testing; - measurementMode = MODE_POSITIVE_BIAS; - range = 5; - operatingMode = SINGLE; - configureSensor(); - - // get measurement - buf[0] = 0x01; - sendData(0x02, buf[0]); - Delay.msDelay(6); - fetch(dummy, 0); - - // test for limits; - for (int axis = 0; axis < 3; axis++) - if (dummy[axis] > 243 && dummy[axis] < 575) - ret[axis] = true; - else - ret[axis] = false; - - // restore settings; - measurementMode = currentMode; - range = currentRange; - operatingMode = currentOperatingMode; - configureSensor(); - - return ret; - } - - public void setSampleRate(float rate) { - for (int i = 0; i < RATES.length; i++) - if (RATES[i] == rate) - rate = i; - configureSensor(); - } - - public float[] getSampleRates() { - return RATES; - } - - public void start() { - this.setOperatingMode(CONTINUOUS); - } - - public void stop() { - this.setOperatingMode(IDLE); - } - - public float getSampleRate() { - return RATES[rate]; - } - - public void setRange(float range) { - for (int i = 0; i < RANGES.length; i++) - if (RANGES[i] == range) - range = i; - configureSensor(); - } - - public float[] getRanges() { - return RANGES; - } - - private void fetch(float[] ret, int offset) { - // The order of data registers seems to be X,Z,Y. (Aswin). - getData(REG_MAGNETO, buf, 6); - ret[0 + offset] = EndianTools.decodeShortBE(buf, 0) * multiplier; - ret[1 + offset] = EndianTools.decodeShortBE(buf, 4) * multiplier; - ret[2 + offset] = EndianTools.decodeShortBE(buf, 2) * multiplier; - } - - private class MagneticMode implements SensorMode { - - /** - * Fills an array of floats with measurements from the sensor in the - * specified unit. - *

    - * The array order is X, Y, Z - *

    - * When the sensor is idle zeros will be returned. - */ - public void fetchSample(float[] sample, int offset) { - // get raw data - switch (operatingMode) { - case (SINGLE): - fetchSingleMeasurementMode(sample, offset); - break; - case (CONTINUOUS): - fetch(sample, offset); - break; - default: - for (int axis = 0; axis < 3; axis++) - sample[axis + offset] = Float.NaN; - break; - } - } - - public int sampleSize() { - return 3; - } - - @Override - public String getName() { - return "Magnetic"; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterGPSSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterGPSSensor.java deleted file mode 100644 index a57cd9f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterGPSSensor.java +++ /dev/null @@ -1,280 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; -import lejos.utility.EndianTools; - -/** - * Dexter dGPS sensor
    - * Sends GPS coordinates to your robot and calculates navigation information - *

    - * The code for this sensor has not been tested. Please report test results to the leJOS forum. - *

    - * - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    PositionGets the coordinates of the sensorlatitude and longitude {@link #getPositionMode() }
    AngleGets the heading of the sensordegrees {@link #getAngleMode() }
    VelocityGets the velocity (speed) of the sensormetres/second {@link #getVelocityMode() }
    Timegets the timeUTC (hhmmss) {@link #getTimeMode() }
    - * - * - *

    - * Sensor configuration
    - * There are no configurable parameters.
    - * The status of the sensor can be checked using the {@link #linkStatus} method. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * - *

    - * - * - * @author Mark Crosbie - * - */ -public class DexterGPSSensor extends I2CSensor { - - public static final byte DGPS_I2C_ADDR = 0x06; /* !< Barometric sensor device address */ - public static final byte DGPS_CMD_UTC = 0x00; /* !< Fetch UTC */ - public static final byte DGPS_CMD_STATUS = 0x01; /* !< Status of satellite link: 0 no link, 1 link */ - public static final byte DGPS_CMD_LAT = 0x02; /* !< Fetch Latitude */ - public static final byte DGPS_CMD_LONG = 0x04; /* !< Fetch Longitude */ - public static final byte DGPS_CMD_VELO = 0x06; /* !< Fetch velocity in cm/s */ - public static final byte DGPS_CMD_HEAD = 0x07; /* !< Fetch heading in degrees */ - public static final byte DGPS_CMD_DIST = 0x08; /* !< Fetch distance to destination */ - public static final byte DGPS_CMD_ANGD = 0x09; /* !< Fetch angle to destination */ - public static final byte DGPS_CMD_ANGR = 0x0A; /* !< Fetch angle travelled since last request */ - public static final byte DGPS_CMD_SLAT = 0x0B; /* !< Set latitude of destination */ - public static final byte DGPS_CMD_SLONG = 0x0C; /* !< Set longitude of destination */ - - private byte reply[] = new byte[4]; - - /** - * Constructor - * - * @param i2cPort - * the i2c port the sensor is connected to - */ - public DexterGPSSensor(I2CPort i2cPort) { - super(i2cPort, DGPS_I2C_ADDR); - init(); - } - - /** - * Constructor - * - * @param sensorPort - * the sensor port the sensor is connected to - */ - public DexterGPSSensor(Port sensorPort) { - super(sensorPort, DGPS_I2C_ADDR); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new PositionMode(), new AngleMode(), new VelocityMode(), new TimeMode() }); - } - - /** - * Return status of link to the GPS satellites LED on dGPS should light if satellite lock acquired - * - * @return true if GPS link is up, else false - */ - public boolean linkStatus() { - this.getData(DGPS_CMD_STATUS, reply, 0, 1); - return (reply[0] == 1); - } - - /** - * Dexter dGPS sensor, Position mode
    - * Gets the coordinates of the sensor - * - *

    - * Size and content of the sample
    - * The sample contains 2 elements. The first element is latitude, the second longitude.
    - * The sensor uses an integer-based representation of latitude and longitude values. Assume that you want to convert the value of 77 degrees, 2 minutes and 54.79 seconds to the integer-based - * representation. The integer value is computed as follows: R = 1000000 * (D + M / 60 + S / 3600) where D=77, M=2, and S=54.79. For the given - * values, the formula yields the integer value 77048553. Basically, this is equivalent to decimal degrees times a million. - * - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getPositionMode() { - return getMode(0); - } - - private class PositionMode implements SensorMode { - - @Override - public int sampleSize() { - return 2; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DGPS_CMD_LAT, reply, 0, 4); - sample[0 + offset] = EndianTools.decodeIntBE(reply, 0) / 1000000f; - - getData(DGPS_CMD_LONG, reply, 0, 4); - sample[1 + offset] = EndianTools.decodeIntBE(reply, 0) / 1000000f; - - } - - @Override - public String getName() { - return "Position"; - } - - } - - /** - * Dexter dGPS sensor, Angle mode
    - * Gets the heading of the sensor - * - *

    - * Size and content of the sample
    - * The sample contains one element representing the heading (in degrees) of the sensor. Accurate heading information can only be given when the sensor is in motion. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getAngleMode() { - return getMode(1); - } - - private class AngleMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DGPS_CMD_HEAD, reply, 0, 2); - sample[offset] = -EndianTools.decodeUShortBE(reply, 0); - } - - @Override - public String getName() { - return "Angle"; - } - - } - - /** - * Dexter dGPS sensor, Velocity mode
    - * Gets the velocity (speed) of the sensor - * - *

    - * Size and content of the sample
    - * The sample contains one elements giving the speed of the sensor (in metres/second). - * - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getVelocityMode() { - return getMode(2); - } - - private class VelocityMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DGPS_CMD_VELO, reply, 1, 3); - reply[0] = 0; - sample[offset] = EndianTools.decodeIntBE(reply, 0) / 100f; - } - - @Override - public String getName() { - return "Velocity"; - } - - } - - /** - * Dexter dGPS sensor, Time mode
    - * gets the UTC time from the sensor - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the UTC time (hhmmss) . - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getTimeMode() { - return getMode(3); - } - - private class TimeMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DGPS_CMD_UTC, reply, 0, 4); - sample[offset] = EndianTools.decodeIntBE(reply, 0); - } - - @Override - public String getName() { - return "Time"; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterIMUSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterIMUSensor.java deleted file mode 100644 index e558781..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterIMUSensor.java +++ /dev/null @@ -1,379 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - -/** - * Dexter Industries dIMU Sensor
    - * An accelerometer and gyroscope for the LEGO® MINDSTORMS® NXT and EV3. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RateThe Rate mode measures the angular speed of the sensor over three axesDegrees/second {@link #getRateMode() }
    AccelerationThe Acceleration mode measures the linear acceleration of the sensor over three axesMetres/second^2 {@link #getAccelerationMode() }
    TemperatureThe Temperature mode measures the internal temperature of the sensors gyroscope ICDegrees Celcius {@link #getTemperatureMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor cannot be configured directly. The internal update frequency of the sensor is adjusted automaticly to match the I2C port speed. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * - *

    - * - * - * @author Aswin Bouwmeester - * - */ -public class DexterIMUSensor extends BaseSensor implements SensorModes { - // TODO: Add support for sensor configuration - - // I2C Addresses for the gyro and acceleration chips with the default values - protected int Accel_I2C_address = 0x3A; - protected int Gyro_I2C_address = 0xD2; - - public DexterIMUSensor(I2CPort port) { - DexterIMUGyroSensor gyro = new DexterIMUGyroSensor(port, Gyro_I2C_address); - setModes(new SensorMode[] { gyro.getMode(0), new DexterIMUAccelerationSensor(port, Accel_I2C_address), gyro.getMode(1) }); - } - - public DexterIMUSensor(Port port) { - DexterIMUGyroSensor gyro = new DexterIMUGyroSensor(port, Gyro_I2C_address); - setModes(new SensorMode[] { gyro.getMode(0), new DexterIMUAccelerationSensor(gyro.port, Accel_I2C_address), gyro.getMode(1) }); - releaseOnClose(gyro); - } - - /** - * Gives a SampleProvider thst returns acceleration (m/s) samples. - * - * @return a SampleProvider - */ - - /** - * Dexter Industries dIMU Sensor, Acceleration Mode
    - * The Acceleration mode measures the linear acceleration of the sensor over three axes - * - *

    - * Size and content of the sample
    - * The sample contains three elements. Each element gives the linear acceleration (in metres/second^2) of the sensor over a single axis. The order of the axes in the sample is X, Y and Z. - * - *

    - * Configuration
    - * The sensor is configured for a dynamic range of -2G tot 2G and an internal update rate of 125 Hertz. Currently there are no configurable settings. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See Freescale MMA7455L datasheet - */ - public SampleProvider getAccelerationMode() { - return getMode(1); - } - - /** - * Dexter Industries dIMU Sensor, Rate Mode
    - * The Rate mode measures the angular speed of the sensor over three axes - * - *

    - * Size and content of the sample
    - * The sample contains three elements. Each element gives the angular speed (in degrees/second) of the sensor over a single axis. The order of the axes in the sample is X, Y and Z. - * - *

    - * Configuration
    - * The sensor is configured for a dynamic range from -2000 to 2000 degrees/second. The internal sample rate is 100 Hertz by default and 400 Hertz when the sensor port is configured for high speed. - * Currently there are no configurable settings. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See ST L3G4200D datasheet - */ - public SampleProvider getRateMode() { - return getMode(0); - } - - /** - * Dexter Industries dIMU Sensor, Temperature Mode
    - * The Temperature mode measures the internal temperature of the sensors gyroscope IC - * - *

    - * Size and content of the sample
    - * The sample contains one elements providing the internal temperature (in gegrees Celcius) of the gyro sensors. Please note that the internal temperature of the sensor will exceed the temperature - * of the environment when the sensor is in use. - * - *

    - * Configuration
    - * The temperature range of the sensor is -40 to 85 degrees Celcius. The update rate is 1 Hertz. There are no configurable settings. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for SampleProviders} - * See ST L3G4200D datasheet - */ - public SampleProvider getTemperatureMode() { - return getMode(2); - } - - /** - * Provides access to the gyro sensor on the IMU.
    - * The Gyro sensor is the L3G4200D from ST. - * - * @author Aswin - * - */ - private class DexterIMUGyroSensor extends I2CSensor { - - // Register adresses - private static final int CTRL_REG1 = 0x020; - private static final int CTRL_REG2 = 0x021; - private static final int CTRL_REG3 = 0x022; - private static final int CTRL_REG4 = 0x023; - private static final int CTRL_REG5 = 0x024; - private static final int REG_STATUS = 0x27; - - // Configurable parameters - // This sensor can configured for samplerate and range. Currently only the - // default values are set. - // The code to set other values is there. - - // private float[] RATES = { 100,200,400,800}; - private int[] RATECODES = { 0x00, 0x40, 0x80, 0xC0 }; - // private float[] RANGES = { 250,500,2000}; - private int[] RANGECODES = { 0x00, 0x10, 0x20 }; - private float[] MULTIPLIERS = { 8.75f, 17.5f, 70f }; - - private int range = 2; - private int rate = 0; - private float toSI = 1f / MULTIPLIERS[range]; - - private byte[] buf = new byte[7]; - - public DexterIMUGyroSensor(I2CPort port, int address) { - super(port, address); - if (port.getType() == I2CPort.TYPE_HIGHSPEED) - rate = 2; - init(); - } - - public DexterIMUGyroSensor(Port port, int address) { - super(port, address, TYPE_LOWSPEED_9V); - init(); - } - - /** - * This method configures the sensor - */ - private void init() { - setModes(new SensorMode[] { new RateMode(), new TemperatureMode() }); - int reg; - // put in sleep mode; - sendData(CTRL_REG1, (byte) 0x08); - // oHigh-pass cut off 1 Hz; - // sendData(CTRL_REG2, (byte) 0x00); - sendData(CTRL_REG2, (byte) 0x19); - // no interrupts, no fifo - sendData(CTRL_REG3, (byte) 0x00); - // set range - reg = RANGECODES[range] | 0x80; - toSI = MULTIPLIERS[range] / 1000f; - sendData(CTRL_REG4, (byte) reg); - // disable fifo and high pass - // sendData(CTRL_REG5, (byte) 0x00); - sendData(CTRL_REG5, (byte) 0x13); - // stabilize output signal; - // enable all axis, set output data rate ; - // reg = RATECODES[rate] | 0x3F; - reg = RATECODES[rate] | 0x0F; - // set sample rate, wake up - sendData(CTRL_REG1, (byte) reg); - float[] dummy = new float[3]; - SampleProvider gyro = getGyroMode(); - for (int s = 1; s <= 15; s++) { - // while (!isNewDataAvailable()) - // Thread.yield(); - gyro.fetchSample(dummy, 0); - } - } - - /** - * Returns true if new data is available from the sensor - */ - @SuppressWarnings("unused") - private boolean isNewDataAvailable() { - getData(REG_STATUS, buf, 1); - if ((buf[0] & 0x08) == 0x08) - return true; - return false; - } - - @SuppressWarnings("unused") - private boolean dataOverrun() { - getData(REG_STATUS, buf, 1); - return ((buf[0] & 0x80) == 0); - } - - /** - * Provides access to the temperature data on the Gyro sensor Method added for consistency with other SensoModes - * - * @return - */ - @SuppressWarnings("unused") - public SampleProvider getTemperatureMode() { - return getMode(1); - } - - /** - * Provides access to the rate data on the gyro sensor - * - * @return - */ - public SampleProvider getGyroMode() { - return getMode(0); - } - - /** - * Represent the gyro sensor in temperature mode - * - * @author Aswin - * - */ - private class TemperatureMode implements SampleProvider, SensorMode { - private static final int DATA_REG = 0x26 | 0x80; - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - // Temperature in degrees - getData(DATA_REG, buf, 1); - sample[offset] = buf[0]; - } - - @Override - public String getName() { - return "Temperature"; - } - - } - - /** - * Represent the gyro sensor in rate mode - * - * @author Aswin - * - */ - private class RateMode implements SampleProvider, SensorMode { - private static final int DATA_REG = 0x27 | 0x80; - - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - buf[0] = 0; - getData(DATA_REG, buf, 7); - - // a correction for misalignment of the gyro sensor is made here - sample[offset] = EndianTools.decodeShortLE(buf, 3) * toSI; - sample[1 + offset] = -EndianTools.decodeShortLE(buf, 1) * toSI; - sample[2 + offset] = EndianTools.decodeShortLE(buf, 5) * toSI; - } - - @Override - public String getName() { - return "Rate"; - } - } - } - - /** - * Class to access the Acceleration sensor from Dexter Industries IMU the acceleration sensor is the Freescale MMA7455 - * - * @author Aswin - * - */ - public class DexterIMUAccelerationSensor extends I2CSensor implements SampleProvider, SensorMode { - protected static final int DATA_10BIT_REG = 0x00; - protected static final int DATA_8BIT_REG = 0x06; - protected static final int MODE_REG = 0x16; - protected static final float TOSI = 100f / (64.0f * 9.81f); - - private byte[] buf = new byte[6]; - - private DexterIMUAccelerationSensor(I2CPort port, int address) { - super(port, address); - // configuure for 2G measurement mode - sendData(MODE_REG, (byte) 0x05); - } - - @Override - public int sampleSize() { - return 3; - } - - private void fetchSample10(float[] sample, int offset) { - getData(DATA_10BIT_REG, buf, 6); - for (int i = 0; i < 3; i++) { - buf[i * 2 + 1] = (byte) ((byte) (buf[i * 2 + 1] << 6) >> 6); - sample[i + offset] = EndianTools.decodeShortLE(buf, i * 2); - sample[i + offset] *= TOSI; - } - } - - @SuppressWarnings("unused") - private void fetchSample8(float[] sample, int offset) { - getData(DATA_8BIT_REG, buf, 3); - for (int i = 0; i < 3; i++) { - sample[i + offset] = buf[i] * TOSI; - } - } - - @Override - public String getName() { - return "Acceleration"; - } - - @Override - public void fetchSample(float[] sample, int offset) { - fetchSample10(sample, offset); - } - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterLaserSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterLaserSensor.java deleted file mode 100644 index d2f8320..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterLaserSensor.java +++ /dev/null @@ -1,181 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - -/** - *

    - * This class represents a Dexter Industries Laser Sensor. The sensor contains a laser and a photodiode to read ambient light values. This sensor can be calibrated to low and high values. - *

    - * - *

    - * The Dexter Industries laser can turn on and off very rapidly, with the following characteristics: - *

    - *
  • it takes about 8-10 ms to turn on and reach full power
  • it takes about 5 ms to turn off - * - */ - - - -/** - * Dexter laser sensor
    - * The sensor contains a laser and a photodiode to read ambient light values.
    - * The Dexter Industries laser can turn on and off very rapidly, with the following characteristics: - *

    - *
  • it takes about 8-10 ms to turn on and reach full power
  • it takes about 5 ms to turn off - * - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    AmbientMeasures light level with the laser off N/A {@link #getAmbientMode() }
    LaserMeasures light level with the laser on N/A {@link #getLaserMode() }
    - * - * - *

    - * - * - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author ? - * - */public class DexterLaserSensor extends AnalogSensor implements SensorConstants { - protected static final long SWITCH_DELAY = 10; - private boolean laser = false; - - /** - * Create a laser sensor object attached to the specified port, and sets the laser on or off. - * - * @param port - * an already open analog port - */ - public DexterLaserSensor(AnalogPort port) { - super(port); - init(); - } - - /** - * Create a laser sensor object attached to the specified port, and sets the laser on or off. - * - * @param port - * port, e.g. Port.S1 - */ - public DexterLaserSensor(Port port) { - super(port); - init(); - } - - protected void init() { - setLaser(laser); - setModes(new SensorMode[] { new Laser(false,"Ambient"), new Laser(true, "laser") }); - } - - public void setLaser(boolean laserState) { - switchType(laserState ? TYPE_LIGHT_ACTIVE : TYPE_LIGHT_INACTIVE, SWITCH_DELAY); - this.laser = laserState; - } - - /** - * Get a sample provider that returns samples with the laser turned off. - * - * @return the sensor mode - */ - - - - /** - * Dexter laser sensor, Ambient mode
    - * Measures light level with the laser off - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing normalised (range 0-1) light level. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ -public SensorMode getAmbientMode() { - return getMode(0); - } - - - -/** - * Dexter laser sensor, Laser mode
    - * Measures light level with the laser on - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing normalised (range 0-1) light level. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ public SensorMode getLaserMode() { - return getMode(1); - } - - private class Laser implements SensorMode { - - private boolean state; - private String name; - - private Laser(boolean state, String name) { - this.state = state; - this.name = name; - } - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - setLaser(state); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() { - return name; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor250.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor250.java deleted file mode 100644 index 30e96ef..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor250.java +++ /dev/null @@ -1,138 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; - -/** - * Support for Dexter Industries DPressure250 - * Not tested. - * - * See http://www.dexterindustries.com/Products-dPressure.html. - * - * @author Lawrie Griffiths - * - */ - - -/** - * Dexter Industries DPressure250
    - * Pressure sensor for LEGO® MINDSTORMS® EV3 and NXT. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    PressureMeasures the pressure Pascal {@link #getPressureMode() }
    - * - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class DexterPressureSensor250 extends AnalogSensor implements SensorConstants { - /* - * - * Formula from DPRESS-driver.h: - * vRef = 4.85 - * vOut = rawValue * vRef / 1023 - * result = (vOut / vRef - CAL1) / CAL2 - */ - private static final double CAL1 = 0.04; - private static final double CAL2 = 0.00369; - - /* - * Optimized: - * result = rawValue * DPRESS_MULT - DPRESS_OFFSET; - */ - private static final float DPRESS_MULT = (float)(1.0 / (CAL2 )); - private static final float DPRESS_OFFSET = (float)(CAL1 / CAL2); - - public DexterPressureSensor250(AnalogPort port) { - super(port); - init(); - } - - public DexterPressureSensor250(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new PressureMode() }); - port.setTypeAndMode(TYPE_CUSTOM, MODE_RAW); - } - - - - - - - /** - * Dexter Industries DPressure250, Pressure mode
    - * Measures the pressure - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the pressure (in PA) measured by the sensor. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getPressureMode() { - return getMode(0); - - } - - private class PressureMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = (NXTRawValue(normalize(port.getPin1())) * DPRESS_MULT - DPRESS_OFFSET)* 1000f; // in pascals - } - - @Override - public String getName() { - return "Pressure"; - } - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor500.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor500.java deleted file mode 100644 index e2b1e40..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterPressureSensor500.java +++ /dev/null @@ -1,124 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; - -/** - * Dexter Industries DPressure500
    - * Pressure sensor for LEGO® MINDSTORMS® EV3 and NXT. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    PressureMeasures the pressure Pascal {@link #getPressureMode() }
    - * - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */public class DexterPressureSensor500 extends AnalogSensor implements SensorConstants { - /* - * - * Formula from DPRESS-driver.h: - * vRef = 4.85 - * vOut = rawValue * vRef / 1023 - * result = (vOut / vRef - CAL1) / CAL2 - */ - private static final double CAL1 = 0.04; - private static final double CAL2 = 0.0018; - - /* - * Optimized: - * result = rawValue * DPRESS_MULT - DPRESS_OFFSET; - */ - private static final float DPRESS_MULT = (float)(1.0 / CAL2 ); - private static final float DPRESS_OFFSET = (float)(CAL1 / CAL2); - - public DexterPressureSensor500(AnalogPort port) { - super(port); - init(); - } - - public DexterPressureSensor500(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new PressureMode() }); - port.setTypeAndMode(TYPE_CUSTOM, MODE_RAW); - } - - - - - /** - * Dexter Industries DPressure500, Pressure mode
    - * Measures the pressure - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the pressure (in PA) measured by the sensor. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor datasheet - */ - public SampleProvider getPressureMode() { - return getMode(0); - - } - - private class PressureMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = (NXTRawValue(normalize(port.getPin1())) * DPRESS_MULT - DPRESS_OFFSET)* 1000f; // in pascals - } - - @Override - public String getName() { - return "Pressure"; - } - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/DexterThermalIRSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/DexterThermalIRSensor.java deleted file mode 100644 index 51572e5..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/DexterThermalIRSensor.java +++ /dev/null @@ -1,230 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - -/** - * Support for the Dexter Industries Thermal Infrared Sensor. - *

    - * The Dexter Industries Thermal Infrared Sensor reads surface temperatures of objects. - * It is a non-contact thermometer based on the Melexis MLX90614xCC. Detecting the infrared radiation - * from an object, the sensor can read object temperatures between -90\u00b0F and 700\u00b0F - * (-70\u00b0C and +380\u00b0C). The sensor has a high accuracy of 0.5\u00b0C and a resolution of 0.02\u00b0C. - *

    - * The Thermal Infrared Sensor reads both the ambient temperature (the temperature of the air - *around the sensor) and the surface temperature of the object that the sensor is pointed towards. - * - * @author Kirk P. Thompson - * - */ - - - - -/** - * Dexter Industries Thermal Infrared Sensor
    - * The Dexter Industries Thermal Infrared Sensor reads surface temperatures of objects. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    ObjectMeasures the temperature of an objects surfaceKelvin {@link #getObjectMode() }
    AmbientMeasures the ambient temperatureKelvin {@link #getAmbientMode() }
    - * - * - *

    - * Sensor configuration
    - * The Emissivity value of the sensor can be configured using the {@link #setEmissivity} method. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Kirk P. Thompson - * - */public class DexterThermalIRSensor extends I2CSensor { - private static final int I2C_ADDRESS = 0x0E; - private static final int REG_GET_OBJECT = 0x01; - private static final int REG_GET_AMBIENT = 0x00; - private static final int REG_GET_EMISSIVITY = 0x03; - private static final int REG_SET_EMISSIVITY = 0x02; - private static final int MAX_EMISSIVITY = 10000; - - private byte [] buf = new byte[2]; - - /** - * Construct a sensor instance that is connected to port. - * @param port The NXT port to use - */ - public DexterThermalIRSensor(I2CPort port) { - super(port, I2C_ADDRESS); - init(); - } - - public DexterThermalIRSensor(Port port) { - super(port, I2C_ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new ObjectMode(), new AmbientMode() }); - } - - /** - * Set the sensor's emissivity value. Valid values are - * 0.01-1.0. The emissivity is stored in non-volatile memory of the sensor and will be - * retained even after power-off. - *

    - * < 0.01 returns with no action. > 1.0 sets to 1.0 - * @param emissivity The value to set emissivity coefficient to - */ - public synchronized void setEmissivity(float emissivity){ - int intEmissivity = Math.round(emissivity * MAX_EMISSIVITY); - if (intEmissivity<100) return; - if (intEmissivity>MAX_EMISSIVITY) intEmissivity=MAX_EMISSIVITY; - - EndianTools.encodeShortBE(intEmissivity, buf, 0); - sendData(REG_SET_EMISSIVITY, buf, 2); - Delay.msDelay(500); - } - - /** - * Read the current emissivity value. - *

    - * Caveat Emptor: The sensor appears to only return the emissivity value - * after it was intially set after power-up with setEmissivity(). It doesn't seem - * to retrieve it from EEPROM. - * - * @return The emissivity value from 0.01 to 1.0 - */ - public float getEmissivity(){ - getData(REG_GET_EMISSIVITY, buf, 2); - return EndianTools.decodeUShortLE(buf, 0) / 65535f; - } - - @Override - public String getProductID() { - return "dTIR"; - } - - @Override - public String getVendorID() { - return "Dexter"; - } - - - - - /** - * Dexter Industries Thermal Infrared Sensor, Object mode
    - * Measures the temperature of an objects surface - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the surface temperature (in Kelvin) of an object. the sensor can read object temperatures between -90\u00b0F and 700\u00b0F - * (-70\u00b0C and +380\u00b0C). The sensor has a high accuracy of 0.5\u00b0C and a resolution of 0.02\u00b0C. - - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor datasheet - */ - public SensorMode getObjectMode() { - return getMode(0); - } - - private class ObjectMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(REG_GET_OBJECT, buf, 2); - sample[offset] = .02f * EndianTools.decodeUShortLE(buf, 0); // degrees Kelvin - } - - @Override - public String getName() { - return "Object"; - } - - } - - - - /** - * Dexter Industries Thermal Infrared Sensor, Ambient mode
    - * Measures the ambient temperature - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the ambient temperature (in Kelvin) (the temperature of the air around the sensor). - - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor datasheet - */ public SensorMode getAmbientMode() { - return getMode(1); - } - - private class AmbientMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(REG_GET_AMBIENT, buf, 2); - sample[offset] = .02f * EndianTools.decodeUShortLE(buf, 0); // degrees Kelvin - } - - @Override - public String getName() { - return "Ambient"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/EV3ColorSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/EV3ColorSensor.java deleted file mode 100644 index c46f570..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/EV3ColorSensor.java +++ /dev/null @@ -1,319 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.robotics.Color; -import lejos.robotics.ColorIdentifier; -import lejos.robotics.LampController; - - -/** - * EV3 color sensor
    - * The digital EV3 Color Sensor distinguishes between eight different colors. It also serves as a light sensor by detecting light intensities. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Color IDMeasures the color ID of a surfaceColor ID {@link #getColorIDMode() }
    RedMeasures the intensity of a reflected red light N/A, Normalized to (0-1) {@link #getRedMode() }
    RGBMeasures the RGB color of a surfaceN/A, Normalized to (0-1) {@link #getRGBMode() }
    AmbientMeasures the ambient light levelN/A, Normalized to (0-1) {@link #getAmbientMode() }
    - * - * - *

    - * Sensor configuration
    - * The flood light of the sensor can be put on or off using the setFloodlight methods. - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Andy - * - */ -public class EV3ColorSensor extends UARTSensor implements LampController, ColorIdentifier -{ - // TODO: decide what to do to the LampController and ColorIdentifier interfaces - protected static int[] colorMap = - { - Color.NONE, Color.BLACK, Color.BLUE, Color.GREEN, Color.YELLOW, Color.RED, Color.WHITE, Color.BROWN - }; - protected static final int SWITCH_DELAY = 250; - - protected static final int COL_RESET = -1; - protected static final int COL_REFLECT = 0; - protected static final int COL_AMBIENT = 1; - protected static final int COL_COLOR = 2; - protected static final int COL_REFRAW = 3; - protected static final int COL_RGBRAW = 4; - protected static final int COL_CAL = 5; - // following maps operating mode to lamp color - // NONE, BLACK, BLUE, GREEN, YELLOW, RED, WHITE, BROWN - protected static final int []lightColor = {Color.NONE, Color.RED, Color.BLUE, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE}; - protected short[]raw = new short[3]; - - private class ModeProvider implements SensorMode - { - final int mode; - final int sampleSize; - final String name; - - ModeProvider(String name, int mode, int sz) - { - this.name = name; - this.mode = mode; - sampleSize = sz; - } - - @Override - public int sampleSize() - { - return sampleSize; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - switchMode(mode, SWITCH_DELAY); - if (sampleSize == 1) - sample[offset] = (float) (port.getByte() & 0xff)/100.0f; - else - { - port.getShorts(raw, 0, raw.length); - for(int i = 0; i < sampleSize; i++) - sample[offset+i] = (float)raw[i]/1020.0f; - } - } - - @Override - public String getName() - { - return name; - } - - } - - protected void initModes() - { - setModes(new SensorMode[]{new ColorIDMode(), new ModeProvider("Red", COL_REFLECT, 1), new ModeProvider("RGB", COL_RGBRAW, 3), new ModeProvider("Ambient", COL_AMBIENT, 1) }); - } - - public EV3ColorSensor(UARTPort port) - { - super(port); - initModes(); - } - - public EV3ColorSensor(Port port) - { - super(port); - initModes(); - } - - - /** {@inheritDoc} - */ - @Override - public int getColorID() - { - setFloodlight(Color.WHITE); - return colorMap[port.getByte()]; - } - - /** {@inheritDoc} - */ - @Override - public void setFloodlight(boolean floodlight) - { - setFloodlight(floodlight ? Color.RED : Color.NONE); - } - - /** {@inheritDoc} - */ - @Override - public boolean isFloodlightOn() - { - return lightColor[currentMode+1] != Color.NONE; - } - - /** {@inheritDoc} - */ - @Override - public int getFloodlight() - { - return lightColor[currentMode+1]; - } - - /** {@inheritDoc} - */ - @Override - public boolean setFloodlight(int color) - { - int mode; - switch (color) - { - case Color.BLUE: - mode = COL_AMBIENT; - break; - case Color.WHITE: - mode = COL_COLOR; - break; - case Color.RED: - mode = COL_REFLECT; - break; - case Color.NONE: - mode = COL_RESET; - break; - default: - // TODO: Should we ignore a wrong color or throw an exception? - throw new IllegalArgumentException("Invalid color specified"); - } - switchMode(mode, SWITCH_DELAY); - return true; - } - - - /** - * EV3 color sensor, Color ID mode
    - * Measures the color ID of a surface. The sensor can identify 8 unique colors (NONE, BLACK, BLUE, GREEN, YELLOW, RED, WHITE, BROWN). - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the ID (0-7) of the detected color. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SensorMode getColorIDMode() - { - return getMode(0); - } - - private class ColorIDMode implements SensorMode{ - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(COL_COLOR, SWITCH_DELAY); - sample[offset]=colorMap[port.getByte()]; - } - - @Override - public String getName() { - return "ColorID"; - } - - } - - - /** - * EV3 color sensor, Red mode
    - * Measures the level of reflected light from the sensors RED LED. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the intensity level (Normalized between 0 and 1) of reflected light. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SensorMode getRedMode() - { - return getMode(1); - } - - - /** - * EV3 color sensor, Ambient mode
    - * Measures the level of ambient light while the sensors lights are off. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the intensity level (Normalized between 0 and 1) of ambient light. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SensorMode getAmbientMode() - { - return getMode(3); - } - - /** - * get a sample provider that returns the light values (RGB) when illuminated by a - * white light source. - * @return the sample provider - */ - /** - * EV3 color sensor, RGB mode
    - * Measures the level of red, green and blue light when illuminated by a white light source.. - * - *

    - * Size and content of the sample
    - * The sample contains 3 elements containing the intensity level (Normalized between 0 and 1) of red, green and blue light respectivily. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SensorMode getRGBMode() - { - //TODO: Should this return 3 or 4 values, 4 values would require an extra mode switch to get ambient value. - return getMode(2); - } - - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/EV3GyroSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/EV3GyroSensor.java deleted file mode 100644 index dba6083..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/EV3GyroSensor.java +++ /dev/null @@ -1,225 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.robotics.SampleProvider; - -/** - * EV3 Gyro sensor
    - * The digital EV3 Gyro Sensor measures the sensors rotational motion and changes in its orientation. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    AngleMeasures the orientation of the sensorDegrees {@link #getAngleMode() }
    RateMeasures the angular velocity of the sensorDegrees / second {@link #getRateMode() }
    Rate and AngleMeasures both angle and angular velocityDegrees, Degrees / second {@link #getAngleAndRateMode() }
    - * - * - *

    - * Sensor configuration
    - * Use {@link #reset()} to recalibrate the sensor and to reset accumulated angle to zero. Keep the sensor motionless during a reset. - * The sensor shuld also be motionless during initialization. - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Andy, Aswin Bouwmeester - * - */ -public class EV3GyroSensor extends UARTSensor { - private static final long SWITCHDELAY = 200; - private short[] raw=new short[2]; - - public EV3GyroSensor(Port port) { - super(port, 3); - setModes(new SensorMode[] { new RateMode(), new AngleMode(), new RateAndAngleMode() }); - - } - - public EV3GyroSensor(UARTPort port) { - super(port, 3); - setModes(new SensorMode[] { new RateMode(), new AngleMode(), new RateAndAngleMode() }); - } - - - /** - * EV3 Gyro sensor, Angle mode
    - * Measures the orientation of the sensor in respect to its start orientation. - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the orientation (in Degrees) of the sensor in respect to its start position. - * - *

    - * Configuration
    - * The start position can be set to the current position using the reset method of the sensor. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SampleProvider getAngleMode() { - return getMode(1); - } - - - /** - * EV3 Gyro sensor, Rate mode
    - * Measures angular velocity of the sensor. - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the angular velocity (in Degrees / second) of the sensor. - * - *

    - * Configuration
    - * The sensor can be recalibrated using the reset method of the sensor. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SampleProvider getRateMode() { - return getMode(0); - } - - - /** - * EV3 Gyro sensor, Rate mode
    - * Measures both angle and angular velocity of the sensor. - * - *

    - * Size and content of the sample
    - * The sample contains two elements. The first element contains angular velocity (in degrees / second). The second element contain angle (in degrees). - * - *

    - * Configuration
    - * The sensor can be recalibrated using the reset method of the sensor. - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SampleProvider getAngleAndRateMode() { - return getMode(2); - } - - - /** - * Hardware calibration of the Gyro sensor and reset off accumulated angle to zero.
    - * The sensor should be motionless during calibration. - */ - public void reset() { - // Reset mode (4) is not used here as it behaves eratically. Instead the reset is done implicitly by going to mode 1. - switchMode(1, SWITCHDELAY); - // And back to 3 to prevent another reset when fetching the next sample - switchMode(3, SWITCHDELAY); - } - - private class AngleMode implements SampleProvider, SensorMode { - private static final int MODE = 3; - private static final float toSI = -1; - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(MODE, SWITCHDELAY); - port.getShorts(raw, 0, raw.length); - sample[offset] = raw[0] * toSI; - } - - @Override - public String getName() { - return "Angle"; - } - - } - - private class RateMode implements SampleProvider, SensorMode { - private static final int MODE = 3; - private static final float toSI = -1; - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(MODE, SWITCHDELAY); - port.getShorts(raw, 0, raw.length); - sample[offset] = raw[1] * toSI; - } - - @Override - public String getName() { - return "Rate"; - } - - } - - private class RateAndAngleMode implements SampleProvider, SensorMode { - private static final int MODE = 3; - private static final float toSI = -1; - - @Override - public int sampleSize() { - return 2; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(MODE, SWITCHDELAY); - port.getShorts(raw, 0, raw.length); - for (int i=0;iEV3 Infra Red sensor
    - * The digital EV3 Infrared Seeking Sensor detects proximity to the robot and reads signals emitted by the EV3 Infrared Beacon. The sensor can alse be used as a receiver for a Lego Ev3 IR remote control. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    DistanceMeasures the distance to an object in front of the sensorUndefined {@link #getDistanceMode() }
    SeekLocates up to four beaconsUndefined, undefined {@link #getSeekMode() }

    - * - * EV3 Infra Red sensor
    - * - * The sensor can be used as a receiver for up to four Lego Ev3 IR remote controls using the {@link #getRemoteCommand} and {@link #getRemoteCommands} methods. -* - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author andy - * - */ -public class EV3IRSensor extends UARTSensor -{ - protected final static int IR_PROX = 0; - protected final static int IR_SEEK = 1; - protected final static int IR_REMOTE = 2; - - protected final static int SWITCH_DELAY = 250; - - public final static int IR_CHANNELS = 4; - - protected byte [] remoteVals = new byte[IR_CHANNELS]; - - protected void init() - { - setModes(new SensorMode[] {new DistanceMode(), new SeekMode()}); - } - - public EV3IRSensor(UARTPort port) - { - super(port, IR_PROX); - init(); - } - - public EV3IRSensor(Port port) - { - super(port, IR_PROX); - init(); - } - - - /** - * Return the current remote command from the specified channel. Remote commands - * are a single numeric value which represents which button on the Lego IR - * remote is currently pressed (0 means no buttons pressed). Four channels are - * supported (0-3) which correspond to 1-4 on the remote. The button values are:
    - * 1 TOP-LEFT
    - * 2 BOTTOM-LEFT
    - * 3 TOP-RIGHT
    - * 4 BOTTOM-RIGHT
    - * 5 TOP-LEFT + TOP-RIGHT
    - * 6 TOP-LEFT + BOTTOM-RIGHT
    - * 7 BOTTOM-LEFT + TOP-RIGHT
    - * 8 BOTTOM-LEFT + BOTTOM-RIGHT
    - * 9 CENTRE/BEACON
    - * 10 BOTTOM-LEFT + TOP-LEFT
    - * 11 TOP-RIGHT + BOTTOM-RIGHT
    - * @param chan channel to obtain the command for - * @return the current command - */ - public int getRemoteCommand(int chan) - { - switchMode(IR_REMOTE, SWITCH_DELAY); - port.getBytes(remoteVals, 0, remoteVals.length); - return remoteVals[chan] & 0xff; - } - - /** - * Obtain the commands associated with one or more channels. Each element of - * the array contains the command for the associated channel (0-3). - * @param cmds the array to store the commands - * @param offset the offset to start storing - * @param len the number of commands to store. - */ - public void getRemoteCommands(byte[] cmds, int offset, int len) - { - switchMode(IR_REMOTE, SWITCH_DELAY); - port.getBytes(cmds, offset, len); - } - - - /** - * EV3 Infra Red sensor, Distance mode
    - * Measures the distance to an object in front of the sensor. - * - *

    - * Size and content of the sample
    - * The sample contains one element giving the distance to an object in front of the sensor. The distance provided is very roughly equivalent to meters - * but needs conversion to give better distance. See product page for details.
    - * The effective range of the sensor in Distance mode is about 5 to 50 centimeters. Outside this range a zero is returned - * for low values and positive infinity for high values. - * - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor Product page - */ public SensorMode getDistanceMode() - { - return getMode(0); - } - - - private class DistanceMode implements SensorMode { - private static final float toSI = 1f; - - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - switchMode(IR_PROX, SWITCH_DELAY); - int raw=((int)port.getByte() & 0xff); - if (raw<5) sample[offset]=0; - else if (raw>55) sample[offset]=Float.POSITIVE_INFINITY; - else sample[offset]=raw*toSI; - } - - @Override - public String getName() - { - return "Distance"; - } - - } - - - /** - * EV3 Infra Red sensor, Seek mode
    - * In seek mode the sensor locates up to four beacons and provides bearing and distance of each beacon. - * - *

    - * Size and content of the sample
    - * The sample contains four pairs of elements in a single sample. Each pair gives bearing of and distance to the beacon. - * The first pair of elements is associated with a beacon transmitting on channel 0, the second pair with a beacon transmitting on channel 1 etc.
    - * The bearing values range from -25 to +25 (with values increasing clockwise - * when looking from behind the sensor). A bearing of 0 indicates the beacon is - * directly in front of the sensor.
    - * Distance values are not to scale. Al increasing values indicate increasing distance.
    - * If no beacon is detected both bearing is set to zero, and distance to positive infinity. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See Sensor Product page - */ public SensorMode getSeekMode() - { - return getMode(1); - } - - private class SeekMode implements SensorMode - { - private static final float toSI = 1f; - byte []seekVals = new byte[8]; - - @Override - public int sampleSize() - { - return 8; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - switchMode(IR_SEEK, SWITCH_DELAY); - port.getBytes(seekVals, 0, seekVals.length); - for(int i = 0; i < seekVals.length; i += 2) - { - int raw=(int)seekVals[i+1] & 0xff; - if (raw == 128) { - sample[offset++] = 0; - sample[offset++] = Float.POSITIVE_INFINITY; - } - else { - sample[offset++] = seekVals[i] * toSI; - sample[offset++] = (int)seekVals[i+1] & 0xff; - } - } - } - - @Override - public String getName() - { - return "Seek"; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/EV3SensorConstants.java b/ev3classes/src/main/java/lejos/hardware/sensor/EV3SensorConstants.java deleted file mode 100644 index 6d31051..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/EV3SensorConstants.java +++ /dev/null @@ -1,68 +0,0 @@ -package lejos.hardware.sensor; - -/** - * Basic constants for use when accessing EV3 Sensors. - * @author andy - * - */ -public interface EV3SensorConstants -{ - public static final int PORTS = 4; - public static final int MOTORS = 4; - - public static final int CONN_UNKNOWN = 111; //!< Connection is fake (test) - public static final int CONN_DAISYCHAIN = 117; //!< Connection is daisy chained - public static final int CONN_NXT_COLOR = 118; //!< Connection type is NXT color sensor - public static final int CONN_NXT_DUMB = 119; //!< Connection type is NXT analog sensor - public static final int CONN_NXT_IIC = 120; //!< Connection type is NXT IIC sensor - public static final int CONN_INPUT_DUMB = 121; //!< Connection type is LMS2012 input device with ID resistor - public static final int CONN_INPUT_UART = 122; //!< Connection type is LMS2012 UART sensor - public static final int CONN_OUTPUT_DUMB= 123; //!< Connection type is LMS2012 output device with ID resistor^ - public static final int CONN_OUTPUT_INTELLIGENT= 124; //!< Connection type is LMS2012 output device with communication - public static final int CONN_OUTPUT_TACHO= 125; //!< Connection type is LMS2012 tacho motor with series ID resistance - public static final int CONN_NONE = 126; //!< Port empty or not available - public static final int CONN_ERROR = 127; //!< Port not empty and type is invalid^M - - public static final int TYPE_NXT_TOUCH = 1; //!< Device is NXT touch sensor - public static final int TYPE_NXT_LIGHT = 2; //!< Device is NXT light sensor - public static final int TYPE_NXT_SOUND = 3; //!< Device is NXT sound sensor - public static final int TYPE_NXT_COLOR = 4; //!< Device is NXT color sensor - public static final int TYPE_TACHO = 7; //!< Device is a tacho motor - public static final int TYPE_MINITACHO = 8; //!< Device is a mini tacho motor - public static final int TYPE_NEWTACHO = 9; //!< Device is a new tacho motor - public static final int TYPE_THIRD_PARTY_START = 50; - public static final int TYPE_THIRD_PARTY_END = 99; - public static final int TYPE_IIC_UNKNOWN = 100; - public static final int TYPE_NXT_TEST = 101; //!< Device is a NXT ADC test sensor - public static final int TYPE_NXT_IIC = 123; //!< Device is NXT IIC sensor - public static final int TYPE_TERMINAL = 124; //!< Port is connected to a terminal - public static final int TYPE_UNKNOWN = 125; //!< Port not empty but type has not been determined - public static final int TYPE_NONE = 126; //!< Port empty or not available - public static final int TYPE_ERROR = 127; //!< Port not empty and type is invalid - - - public static final int UART_MAX_MODES = 8; - public static final int MAX_DEVICE_DATALENGTH = 32; - public static final int IIC_DATA_LENGTH = MAX_DEVICE_DATALENGTH; - public static final int STATUS_OK = 0; - public static final int STATUS_BUSY = 1; - public static final int STATUS_FAIL = 2; - public static final int STATUS_STOP = 4; - - public static final byte CMD_NONE = (byte)'-'; - public static final byte CMD_FLOAT = (byte)'f'; - public static final byte CMD_SET = (byte)'0'; - public static final byte CMD_AUTOMATIC = (byte) 'a'; - public static final byte CMD_CONNECTED = (byte) 'c'; - public static final byte CMD_DISCONNECTED = (byte) 'd'; - public static final byte CMD_COL_COL = 0xd; - public static final byte CMD_COL_RED = 0xe; - public static final byte CMD_COL_GRN = 0xf; - public static final byte CMD_COL_BLU = 0x11; - public static final byte CMD_COL_AMB = 0x12; - public static final byte CMD_PIN1 = 0x1; - public static final byte CMD_PIN5 = 0x2; - - public static final float ADC_REF = 5.0f; // 5.0 Volts - public static final int ADC_RES = 4095; -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/EV3TouchSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/EV3TouchSensor.java deleted file mode 100644 index 6655b95..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/EV3TouchSensor.java +++ /dev/null @@ -1,113 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - -/** - * Basic sensor driver for the Lego EV3 Touch sensor - * @author andy - * - */ -/** - * Lego EV3 Touch sensor
    - * The analog EV3 Touch Sensor is a simple but exceptionally precise tool that detects when its front button is pressed or released. - * - * * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    TouchDetects when its front button is pressedBinary {@link #getTouchMode() }
    - * - * - * - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Your name - * - */ -public class EV3TouchSensor extends AnalogSensor -{ - - public EV3TouchSensor(AnalogPort port) - { - super(port); - init(); - } - - public EV3TouchSensor(Port port) - { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new TouchMode() }); - } - - - - - /** - * Lego EV3 Touch sensor, Touch mode
    - * Detects when its front button is pressed - * - *

    - * Size and content of the sample
    - * The sample contains one element, a value of 0 indicates that the button is not presse, a value of 1 indicates the button is pressed. - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - */ - public SensorMode getTouchMode() - { - return getMode(0); - } - - - private class TouchMode implements SensorMode { - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - sample[offset] = (port.getPin6() > EV3SensorConstants.ADC_REF/2f ? 1.0f : 0.0f); - } - - @Override - public String getName() - { - return "Touch"; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/EV3UltrasonicSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/EV3UltrasonicSensor.java deleted file mode 100644 index b355727..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/EV3UltrasonicSensor.java +++ /dev/null @@ -1,191 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; -import lejos.robotics.SampleProvider; - -/** - * Lego EV3 Ultrasonic sensor
    - * The EV3 Ultrasonic sensor measures distance to an object in front of the - * sensor. It can also be used to detect other (active) Ultrasonic sensors in - * the vicinity. - * - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    DistanceMeasures distance to an object in front of the sensorMeter {@link #getDistanceMode() }
    ListenListens for other ultrasonic sensorsBoolean {@link #getListenMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be switched off and on using the {@link #enable} and - * {@link #disable} methods. Disabling the sensor also shuts down the lights. - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Aswin Bouwmeester - * - */ -public class EV3UltrasonicSensor extends UARTSensor { - - private static final int DISABLED = 3; - private static final int SWITCHDELAY = 200; - - protected void init() { - setModes(new SensorMode[] { new DistanceMode(), new ListenMode() }); - } - - /** - * Create the Ultrasonic sensor class. - * - * @param port - */ - public EV3UltrasonicSensor(Port port) { - super(port, 0); - init(); - } - - /** - * Create the Ultrasonic sensor class. - * - * @param port - */ - public EV3UltrasonicSensor(UARTPort port) { - super(port, 0); - init(); - } - - /** - * Lego EV3 Ultrasonic sensor, Listen mode
    - * Listens for the presence of other ultrasonic sensors. - * - *

    - * Size and content of the sample
    - * The sample contains one elements indicating the presence of another ultrasonic sensor. - * A value of 1 indicates that the sensor detects another ultrasonic sensor. - * - * @return A sampleProvider - */ - public SampleProvider getListenMode() { - return getMode(1); - } - - /** - * Lego EV3 Ultrasonic sensor, Distance mode
    - * Measures distance to an object in front of the sensor - * - *

    - * Size and content of the sample
    - * The sample contains one elements representing the distance (in metres) to an object in front of the sensor. - * unit). - * - * @return A sampleProvider - */ - public SampleProvider getDistanceMode() { - return getMode(0); - } - - /** - * Enable the sensor. This puts the indicater LED on. - */ - public void enable() { - switchMode(0, SWITCHDELAY); - } - - /** - * Disable the sensor. This puts the indicater LED off. - */ - public void disable() { - switchMode(DISABLED, SWITCHDELAY); - } - - /** - * Indicate that the sensor is enabled. - * - * @return True, when the sensor is enabled.
    - * False, when the sensor is disabled. - */ - public boolean isEnabled() { - return (currentMode == DISABLED) ? false : true; - } - - -private class DistanceMode implements SampleProvider, SensorMode { - private static final int MODE = 0; - private static final float toSI = 0.001f; - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(MODE, SWITCHDELAY); - int raw = port.getShort(); - sample[offset] = (raw == 2550) ? Float.POSITIVE_INFINITY : (float) raw - * toSI; - } - - @Override - public String getName() { - return "Distance"; - } - - } - - /** - * Represents a Ultrasonic sensor in listen mode - */ - private class ListenMode implements SampleProvider, SensorMode { - private static final int MODE = 2; - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchMode(MODE, SWITCHDELAY); - sample[offset] = port.getShort() & 0xff; - } - - @Override - public String getName() { - return "Listen"; - } - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAccelerometer.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAccelerometer.java deleted file mode 100644 index 9b081e6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAccelerometer.java +++ /dev/null @@ -1,163 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - -/** - * HiTechnic NXT Acceleration / Tilt Sensor (NAC1040)
    - * The HiTechnic Accelerometer / Tilt Sensor measures acceleration in three - * axes. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    AccelerationMeasures acceleration over three axes.meter / second2 {@link #getAccelerationMode() }
    - * - * - *

    - * - * See - * Sensor Product page (Some details from HTAC-driver.h from - * http://botbench.com/blog/robotc-driver-suite/) - * - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * @author Michael Mirwaldt - * - */ -public class HiTechnicAccelerometer extends I2CSensor { - private static final int BASE_ACCEL = 0x42; - private static final int OFF_X_HIGH = 0x00; - private static final int OFF_Y_HIGH = 0x01; - private static final int OFF_Z_HIGH = 0x02; - private static final int OFF_2BITS = 3; - private static final float TO_SI = 0.049033251f; - - private byte[] buf = new byte[6]; - - /** - * Creates a SampleProvider for the HiTechnic Acceleration Sensor - * - * @param port - * the I2C port - * @param address - * the I2C address of the sensor - */ - public HiTechnicAccelerometer(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Creates a SampleProvider for the HiTechnic Acceleration Sensor - * - * @param port - * the I2C port - */ - public HiTechnicAccelerometer(I2CPort port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * Creates a SampleProvider for the HiTechnic Acceleration Sensor - * - * @param port - * the sensor port - * @param address - * the I2C address of the sensor - */ - public HiTechnicAccelerometer(Port port, int address) { - super(port, address, TYPE_LOWSPEED_9V); - init(); - } - - /** - * Creates a SampleProvider for the HiTechnic Acceleration Sensor - * - * @param port - * the I2C port - */ - public HiTechnicAccelerometer(Port port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new AccelMode() }); - } - - /** - * HiTechnic NXT Acceleration , Acceleration mode
    - * Measures acceleration over three axes. - * - *

    - * Size and content of the sample
    - * The sample contains 3 elements, containing acceleration over the X, Y and Z - * axis respectively. The range of the sensor is -2 to 2 G (1G = 9.81 - * m/s2). - * - *

    - * - * @return A sampleProvider - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * See - * Sensor datasheet - */ - public SensorMode getAccelerationMode() { - return getMode(0); - } - - private class AccelMode implements SensorMode { - - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(BASE_ACCEL, buf, 0, 6); - - sample[offset + 0] = ((buf[OFF_X_HIGH] << 2) + (buf[OFF_X_HIGH - + OFF_2BITS] & 0xFF)) - * TO_SI; - sample[offset + 1] = ((buf[OFF_Y_HIGH] << 2) + (buf[OFF_Y_HIGH - + OFF_2BITS] & 0xFF)) - * TO_SI; - sample[offset + 2] = ((buf[OFF_Z_HIGH] << 2) + (buf[OFF_Z_HIGH - + OFF_2BITS] & 0xFF)) - * TO_SI; - } - - @Override - public String getName() { - return "Acceleration"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAngleSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAngleSensor.java deleted file mode 100644 index 3a86215..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicAngleSensor.java +++ /dev/null @@ -1,209 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.Delay; -import lejos.utility.EndianTools; - -/** - * Hitechnic Angle sensor
    - * The Angle sensor measures axle rotation position and rotation speed. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Absolute angleMeasures the rotation position of a rotating axleDegrees (0-359) {@link #getAngleMode() }
    Accumulated angleMeasures the accumulated number of degrees an axle has rotatedDegrees {@link #getAccumulatedAngleMode() }
    Angular velocitythe speed of the axle rotationrotations / second {@link #getAngularVelocityMode() }
    - * - * - *

    - * Sensor configuration
    - * The zero position of the sensor can be set and stored in the sensors memory - * using the calibrateAngle method. The accumulated angle can be set to zero - * using the resetAccumulatedAngle method. The accumulated angle is not stored - * in memory. - * - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * - */ -public class HiTechnicAngleSensor extends I2CSensor { - protected static final int REG_ANGLE = 0x42; - protected static final int REG_ACCUMULATED_ANGLE = 0x44; - protected static final int REG_SPEED = 0x48; - protected static final int HTANGLE_MODE_CALIBRATE = 0x43; - protected static final int HTANGLE_MODE_RESET = 0x52; - - private byte buf[] = new byte[4]; - - public HiTechnicAngleSensor(I2CPort port) { - super(port, DEFAULT_I2C_ADDRESS); - init(); - } - - public HiTechnicAngleSensor(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new AngleMode(), new AccumulatedAngleMode(), - new AngularVelocityMode() }); - } - - /** - * Reset the rotation count of accumulated angle to zero. Not saved in EEPORM. - */ - public void resetAccumulatedAngle() { - sendData(0x41, (byte) HTANGLE_MODE_RESET); - } - - /** - * Calibrate the zero position of angle. Zero position is saved in EEPROM on - * sensor. Thread sleeps for 50ms while that is done. - */ - public void calibrateAngle() { - sendData(0x41, (byte) HTANGLE_MODE_CALIBRATE); - Delay.msDelay(50); - } - - /** - * HiTechnic angle sensor, Angle mode
    - * Measures the rotation position of a rotating axle. - * - *

    - * Size and content of the sample
    - * The sample contains one elements containing the angle of the sensor in the range of 0 to 359 degrees. - * - - */ - public SensorMode getAngleMode() { - return getMode(0); - } - - private class AngleMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(REG_ANGLE, buf, 2); - int bits9to2 = buf[0] & 0xFF; - int bit1 = buf[1] & 0x01; - - sample[offset] = (bits9to2 << 1) | bit1; - } - - @Override - public String getName() { - return "Angle"; - } - } - - /** - * HiTechnic angle sensor, Accumulated angle mode
    - * Measures the accumulated number of degrees an axle has rotated. - * - *

    - * Size and content of the sample
    - * The sample contains one elements containing the accumulated rotation (in degrees) of the axle. - */ - public SensorMode getAccumulatedAngleMode() { - return getMode(1); - } - - private class AccumulatedAngleMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(REG_ACCUMULATED_ANGLE, buf, 4); - - sample[offset] = -EndianTools.decodeIntBE(buf, 0); - } - - @Override - public String getName() { - return "AccumulatedAngle"; - } - } - - /** - * HiTechnic angle sensor, Angular velocity mode
    - * Measures the rotational speed of an axle. - * - *

    - * Size and content of the sample
    - * The sample contains one elements containing the angular velocity (in degrees) of the axle. - */ - public SensorMode getAngularVelocityMode() { - return getMode(2); - } - - private class AngularVelocityMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(REG_SPEED, buf, 2); - // 1 rpm = 360°/60sec = 6°/sec - //FIXME shouldn't we multiply by 6 instead of dividing by 60? - sample[offset] = -EndianTools.decodeShortBE(buf, 0) / 60f; - } - - @Override - public String getName() { - return "AngularVelocity"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicBarometer.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicBarometer.java deleted file mode 100644 index ac784c1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicBarometer.java +++ /dev/null @@ -1,201 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.EndianTools; - -/** - * Hitechnic Barometric sensor
    - * The sensor measures both atmospheric pressure and temperature. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    PressureMeasures atmospheric pressurePascal {@link #getPressureMode() }
    TemperatureMeasures temperatureDegree Celcius {@link #getTemperatureMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be calibrated for pressure using the calibrate method. - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Matthias Paul Scholz - * - */ -public class HiTechnicBarometer extends I2CSensor { - - private static final int REG_TEMPERATURE = 0x42; - private static final int REG_PRESSURE = 0x44; - private static final int REG_PRESSURE_CALIBRATION = 0x46; - // Wikipedia: 1 inHg at 0 °C = 3386.389 Pa - private static final float MINHG_TO_PA = 3.38638866667f; - // Wikipedia: Standard Atmosphere is 101325 Pa - private static final float STANDARD_ATMOSPHERIC_PRESSURE = 101325f; - - private final byte[] buffer = new byte[2]; - - /** - * Constructor. - * - * @param port - * the {@link I2CPort} the sensor is connected to. - */ - public HiTechnicBarometer(final I2CPort port) { - super(port, DEFAULT_I2C_ADDRESS); - } - - /** - * Constructor. - * - * @param port - * the {@link I2CPort} the sensor is connected to. - * @param address - * the address - */ - public HiTechnicBarometer(final I2CPort port, final int address) { - super(port, address); - init(); - } - - public HiTechnicBarometer(final Port port, final int address) { - super(port, address, TYPE_LOWSPEED); - init(); - } - - public HiTechnicBarometer(final Port port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new PressureMode(), new TemperatureMode() }); - if (getCalibrationMetric() == 0) - calibrate(STANDARD_ATMOSPHERIC_PRESSURE); - } - - /** - * Re-calibrates the sensor. - * - * @param pascals - * the calibration value in pascals - */ - public void calibrate(float pascals) { - // compute calibration value in 1/1000 inHg - int calibrationImperial = (int)(0.5f + pascals / MINHG_TO_PA); - EndianTools.encodeShortBE(calibrationImperial, buffer, 0); - sendData(REG_PRESSURE_CALIBRATION, buffer, 2); - } - - /** - * @return the present calibration value in pascals. Will be 0 in case no - * explicit calibration has been performed. - */ - public float getCalibrationMetric() { - // get calibration value in 1/1000 inHg - getData(REG_PRESSURE_CALIBRATION, buffer, 2); - int result = EndianTools.decodeUShortBE(buffer, 0); - return result * MINHG_TO_PA; - } - - /** - * HiTechnic Barometer, Pressure mode
    - * Measures the atmospheric pressure of the air. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the atmospheric pressure (in Pascal) of the air. - */ - public SensorMode getPressureMode() { - return getMode(0); - } - - private class PressureMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public String getName() { - return "Pressure"; - } - - @Override - public void fetchSample(float[] sample, int offset) { - // get pressure in 1/1000 inHg - getData(REG_PRESSURE, buffer, 2); - int result = EndianTools.decodeUShortBE(buffer, 0); - sample[0] = result * MINHG_TO_PA; - } - - } - - /** - * HiTechnic Barometer, Temperature mode
    - * Measures the temperature of the air. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the air temperature (in degree celcius). - */ - public SensorMode getTemperatureMode() { - return getMode(1); - } - - private class TemperatureMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - // get temperature in 1/10 °C - getData(REG_TEMPERATURE, buffer, 2); - int result = EndianTools.decodeShortBE(buffer, 0); - sample[offset] = result / 10f + 273.15f; - } - - @Override - public String getName() { - return "Temperature"; - } - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicColorSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicColorSensor.java deleted file mode 100644 index 3463b78..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicColorSensor.java +++ /dev/null @@ -1,179 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.Color; -import lejos.robotics.ColorIdentifier; - -/** - * HiTechnic color sensor.
    - * www.hitechnic.com - * - * This class does support HiTechnic Color Sensor V2. - * - * See http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NCO1038 - * - *@author BB extended by A.T.Brask, converted for EV3 by Lawrie Griffiths - * - */ - -/** - * HiTechnic color sensor
    - * Description - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Color IDMeasures the color ID of a surfaceColor ID {@link #getColorIDMode() }
    RGBMeasures the RGB color of a surfaceN/A, Normalized to (0-1) {@link #getRGBMode() }
    - * - * - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Your name - * - */ -public class HiTechnicColorSensor extends I2CSensor implements ColorIdentifier { - - private byte[] buf = new byte[3]; - - // TODO: Problem: The following table ignores pastels and other subtle colors - // HiTechnic can detect. - // Converting to limited JSE color set means this generic interface isn't as - // rich at describing color - // ID as it could be. - private int[] colorMap = { Color.BLACK, Color.MAGENTA, Color.MAGENTA, - Color.BLUE, Color.GREEN, Color.YELLOW, Color.YELLOW, Color.ORANGE, - Color.RED, Color.RED, Color.MAGENTA, Color.MAGENTA, Color.YELLOW, - Color.PINK, Color.PINK, Color.PINK, Color.MAGENTA, Color.WHITE }; - - public HiTechnicColorSensor(I2CPort port) { - super(port); - init(); - } - - public HiTechnicColorSensor(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new ColorIDMode(), new RGBMode() }); - } - - // INDEX VALUES - - /** - * Returns the color index detected by the sensor. - * - * @return Color index.
    - *

  • 0 = red
  • 1 = green
  • 2 = blue
  • 3 = yellow
  • 4 = - * magenta
  • 5 = orange
  • 6 = white
  • 7 = black
  • 8 = pink
  • - * 9 = gray
  • 10 = light gray
  • 11 = dark gray
  • 12 = cyan - */ - @Override - public int getColorID() { - getData(0x42, buf, 1); - int HT_val = (0xFF & buf[0]); - return colorMap[HT_val]; - } - - /** - * HiTechnic color sensor, Color ID mode
    - * Measures the color ID of a surface. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing a color ID. - *

  • 0 = red
  • 1 = green
  • 2 = blue
  • 3 = yellow
  • 4 = - * magenta
  • 5 = orange
  • 6 = white
  • 7 = black
  • 8 = pink
  • - * 9 = gray
  • 10 = light gray
  • 11 = dark gray
  • 12 = cyan - */ - public SensorMode getColorIDMode() { - return getMode(0); - } - - /** - * HiTechnic color sensor, Color ID mode
    - * Measures the color of a surface. - * - *

    - * Size and content of the sample
    - * The sample contains three elements containing the color expressed in RGB values (0-255) of the measured surface. - */ public SensorMode getRGBMode() { - return getMode(1); - } - - private class ColorIDMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = (float) getColorID(); - } - - @Override - public String getName() { - return "ColorID"; - } - } - - public class RGBMode implements SensorMode { - - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x43, buf, 3); - for (int i = 0; i < 3; i++) - sample[offset + i] = ((float) (0xFF & buf[i])) / 256f; - } - - @Override - public String getName() { - return "RGB"; - } - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicCompass.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicCompass.java deleted file mode 100644 index 9b48464..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicCompass.java +++ /dev/null @@ -1,225 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.Calibrate; - -/** - * This class supports the HiTechnic compass sensor. - * - * See http://www.hitechnic.com/cgi-bin/commerce.cgi?preadd=action&key=NMC1034 - * - */ - -/** - * HiTechnic compass sensor Sensor name
    - * The HiTechnic compass measures the earth's magnetic field and calculates a - * heading angle. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    CompassMeasures the orientation of the sensorDegrees, corresponding to the compass rose {@link #getCompassMode() }
    AngleMeasures the orientation of the sensorDegrees, corresponding to the right hand coordinate system {@link #getAngleMode() }
    - * - * - * - *

    - * Sensor configuration
    - * The sensor can be calibrated for magnetic disturbances coming from the robot - * (soft iron calibration). Use the startCalibration method to put the sensor in - * calibration mode. While in calibration mode the sensor should be rotated - * slowly for making at least 1.5 full rotations. Then end calibration with the - * endCalibration method. - * - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Your name - * - */ -public class HiTechnicCompass extends I2CSensor implements Calibrate { - private final static byte COMMAND = 0x41; - private final static byte BEGIN_CALIBRATION = 0x43; - private final static byte END_CALIBRATION = 0x00; // Back to measurement mode - - byte[] buf = new byte[2]; - - /** - * Create a compass sensor object - * - * @param port - * I2C port for the compass - * @param address - * The I2C address used by the sensor - */ - public HiTechnicCompass(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * I2C port for the compass - */ - public HiTechnicCompass(I2CPort port) { - super(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * Sensor port for the compass - * @param address - * The I2C address used by the sensor - */ - public HiTechnicCompass(Port port, int address) { - super(port, address); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * Sensor port for the compass - */ - public HiTechnicCompass(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new CompassMode(), new AngleMode() }); - } - - /** - * HiTechnic compass sensor, Compass mode
    - * Measures the bearing of the sensor. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the bearing of the sensor relative to north expressed in degrees. East being at 90 degrees. - */ - public SensorMode getCompassMode() { - return getMode(0); - } - - private class CompassMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 2); - sample[offset] = (((buf[0] & 0xff) << 1) + buf[1]); - } - - @Override - public String getName() { - return "Compass"; - } - } - - /** - * HiTechnic compass sensor, Angle mode
    - * Measures the color of a surface. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the bearing of the sensor relative to north expressed in degrees using a right hand coordinate system in the range of (-180 to 180). West being at 90 degrees, east being at -90 degrees. - */ - public SensorMode getAngleMode() { - return getMode(1); - } - - private class AngleMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 2); - sample[offset] = (((buf[0] & 0xff) << 1) + buf[1]); - if (sample[offset] <180 ) { - // correction for right hand coordinate system - sample[offset] = - sample[offset]; - } - else { - sample[offset] = 360 - sample[offset]; - } - } - - @Override - public String getName() { - return "Angle"; - } - } - - - /** - * Starts calibration for the compass. Must rotate *very* slowly, taking at - * least 20 seconds per rotation. - * - * Should make 1.5 to 2 full rotations. Must call stopCalibration() when done. - */ - @Override - public void startCalibration() { - buf[0] = BEGIN_CALIBRATION; - sendData(COMMAND, buf, 1); - } - - /** - * Ends calibration sequence. - * - */ - @Override - public void stopCalibration() { - buf[0] = END_CALIBRATION; - sendData(COMMAND, buf, 1); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicEOPD.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicEOPD.java deleted file mode 100644 index 434714e..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicEOPD.java +++ /dev/null @@ -1,145 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - -/** - * HiTechnic EOPD Sensor
    - * The EOPD or Electro Optical Proximity Detector uses an internal light source to detect the presence of a target or determine changes in distance to a target. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Long DistanceMeasures the relative distance to an objectN/A, a normalized value that represents the relative distance to an object. 0 = minimum range, 1 = maximum range. {@link #getLongDistanceMode() }
    Short DistanceMeasures the relative distance to an objectN/A, a normalized value that represents the relative distance to an object. 0 = minimum range, 1 = maximum range. {@link #getShortDistanceMode() }
    - * - * - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Michael Smith - * - */ - -public class HiTechnicEOPD extends AnalogSensor implements SensorConstants { - - - - protected static final long SWITCH_DELAY = 10; - /** - * @param port NXT sensor port 1-4 - */ - public HiTechnicEOPD (AnalogPort port){ - super(port); - init(); - } - - /** - * @param port NXT sensor port 1-4 - */ - public HiTechnicEOPD (Port port){ - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new LongDistanceMode(), new ShortDistanceMode() }); - } - - - /** - * HiTechnic EOPD sensor, Long distance mode
    - * Measures the relative distance to a surface. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the relative distance to a surface in the range of 0 to 1. - * Where 0 corresponds to the minimum of the measurement range and 1 corresponds to the maximum of the measyurement range. - * The measurement range depends on the color and reflectivity of the measured surface. The measurement is more or less linear to the distance for a given surface. - */ - public SensorMode getLongDistanceMode() { - return getMode(0); - } - - -private class LongDistanceMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchType(TYPE_LIGHT_INACTIVE, SWITCH_DELAY); - sample[offset] = (float) Math.sqrt((normalize(port.getPin1()))); - } - - @Override - public String getName() { - return "Long distance"; - } -} - -/** - * HiTechnic EOPD sensor, Short distance mode
    - * Measures the relative distance to a surface. This mode is suited for white objects at short distance. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the relative distance to a surface in the range of 0 to 1. - * Where 0 corresponds to the minimum of the measurement range and 1 corresponds to the maximum of the measyurement range. - * The measurement range depends on the color and reflectivity of the measured surface. The measurement is more or less linear to the distance for a given surface. - */ public SensorMode getShortDistanceMode() { - return getMode(1); - } - - - - - - public class ShortDistanceMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchType(TYPE_LIGHT_ACTIVE, SWITCH_DELAY); - sample[offset] = (float) Math.sqrt((normalize(port.getPin1()))); - } - - @Override - public String getName() { - return "Short distance"; - } - -} -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicGyro.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicGyro.java deleted file mode 100644 index eff34f6..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicGyro.java +++ /dev/null @@ -1,113 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - - -/** - * HiTechnic NXT Gyro Sensor
    - * The NXT Gyro Sensor contains a single axis gyroscopic sensor that detects rotation. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RateThe Rate mode measures the angular speed of the sensor over a single axisDegrees/second {@link #getRateMode() }
    - * - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class HiTechnicGyro extends AnalogSensor implements SensorConstants { - private static final float TO_SI=-1; - private float zero = 600f; - - /** - * Supports the SampleProvider interface.
    - * The sensor measures the angular velocity in degrees per second. - * A positive rate indicates a counterclockwise rotation. A negative rate indicates a clockwise rotation. - * - * @param port the Analog port - */ - public HiTechnicGyro(AnalogPort port) { - super(port); - init(); - } - - /** - * Supports the SampleProvider interface.
    - * The sensor measures the angular velocity in degrees per second. - * A positive rate indicates a counterclockwise rotation. A negative rate indicates a clockwise rotation. - * - * @param port the Sensor port - */ - public HiTechnicGyro(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new RateMode() }); - port.setTypeAndMode(TYPE_CUSTOM, MODE_RAW); - } - - /** - * HiTechnic Gyro sensor, Rate mode
    - * The Rate mode measures the angular speed of the sensor over three axes - * - *

    - * Size and content of the sample
    - * The sample contains one element giving the angular speed (in degrees/second) of the sensor over its vertical axis (Z-axis). - * - *

    - * */ - public SensorMode getRateMode() { - return getMode(0); - } - - private class RateMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = ((float) NXTRawValue(port.getPin1()) - zero) * TO_SI; - } - - @Override - public String getName() { - return "Rate"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeeker.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeeker.java deleted file mode 100644 index ef4d6eb..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeeker.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - -/** - * HiTechnic NXT IRSeeker
    - * The NXT IRSeeker is a multi-element infrared detector that - * detects infrared signals from sources such as the HiTechnic IRBall soccer - * ball, infrared remote controls and sunlight. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    UnmodulatedMeasures the angle to a source of unmodulated infrared lightDegrees {@link #getUnmodulatedMode() }
    - * - * - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author ? - * - */ -public class HiTechnicIRSeeker extends I2CSensor { - byte[] buf = new byte[1]; - - public HiTechnicIRSeeker(I2CPort port) { - super(port); - init(); - } - - public HiTechnicIRSeeker(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new UnmodulatedMode() }); - } - - /** - * HiTechnic IR seeker, Unmodulated mode
    - * Measures the angle to a source of unmodulated infrared light - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the angle to the infrared source. The angle is expressed in degrees following the right hand rule. - */ - - public SensorMode getUnmodulatedMode() { - return getMode(0); - } - - /** - * Measures angle with zero forward, anti-clockwise positive - */ - private class UnmodulatedMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 1); - float angle = Float.NaN; - if (buf[0] > 0) { - angle = -(buf[0] * 30 - 150); - } - sample[offset] = angle; - } - - @Override - public String getName() { - return "Unmodulated"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeekerV2.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeekerV2.java deleted file mode 100644 index da1f0b5..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicIRSeekerV2.java +++ /dev/null @@ -1,148 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - - -/** - * HiTechnic NXT IRSeeker V2
    - * The NXT IRSeeker V2 (Version 2) is a multi-element infrared detector that - * detects infrared signals from sources such as the HiTechnic IRBall soccer - * ball, infrared remote controls and sunlight. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    modulatedMeasures the angle to a source of modulated (1200 Hz square wave) infrared lightDegrees {@link #getModulatedMode() }
    UnmodulatedMeasures the angle to a source of unmodulated infrared lightDegrees {@link #getUnmodulatedMode() }
    - * - * - *

    - * - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class HiTechnicIRSeekerV2 extends I2CSensor -{ - private static final byte address = 0x10; - private byte[] buf = new byte[1]; - - public HiTechnicIRSeekerV2(I2CPort port) { - super(port, address); - init(); - } - - public HiTechnicIRSeekerV2(Port port) { - super(port, address); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new ModulatedMode(), new UnmodulatedMode() }); - } - - /** - * HiTechnic IR seeker V2, modulated mode
    - * Measures the angle to a source of a modulated infrared light. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the angle to the infrared source. The angle is expressed in degrees following the right hand rule. - */ - public SensorMode getModulatedMode() { - return getMode(0); - } - - private class ModulatedMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x49, buf, 1); - float angle = Float.NaN; - if (buf[0] > 0) { - // Convert to angle with zero forward, anti-clockwise positive - angle = -(buf[0] * 30 - 150); - } - sample[offset] = angle; - } - - @Override - public String getName() { - return "Modulated"; - } - } - - /** - * HiTechnic IR seeker V2, Unmodulated mode
    - * Measures the angle to a source of unmodulated infrared light - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the angle to the infrared source. The angle is expressed in degrees following the right hand rule. - */ - public SensorMode getUnmodulatedMode() { - return getMode(1); - } - - private class UnmodulatedMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 1); - float angle = Float.NaN; - if (buf[0] > 0) { - // Convert to angle with zero forward, anti-clockwise positive - angle = -(buf[0] * 30 - 150); - } - sample[offset] = angle; - } - - @Override - public String getName() { - return "Unmodulated"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicMagneticSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicMagneticSensor.java deleted file mode 100644 index 1fc0b35..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/HiTechnicMagneticSensor.java +++ /dev/null @@ -1,108 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; - - -/** - *
    - * The sensor detects magnetic fields that are present around the front of the sensor in a vertical orientation. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    MagneticMeasures the strength of a vertical magnetic fieldN/A, normalized {@link #getMagneticMode() }
    - * - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */public class HiTechnicMagneticSensor extends AnalogSensor implements SensorConstants {; - - /** - * Create a magnetic sensor on an analog port - * - * @param port the analog port - */ - public HiTechnicMagneticSensor(AnalogPort port) { - super(port); - init(); - } - - /** - * Create a magnetic sensor on a sensor port - * - * @param port the analog port - */ - public HiTechnicMagneticSensor(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new MagneticMode() }); - port.setTypeAndMode(TYPE_CUSTOM, MODE_RAW); - } - - /** - * HiTechnic Magnetic sensor, Magnetic mode
    - * Measures the strength og the vertical magnetic field - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the strength of the magnetic field around the sensor. - * The value is normalized (0-1) where 1 corresponds with the maximum field strength. - */ - public SampleProvider getMagneticMode() { - return getMode(0); - } - - private class MagneticMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = normalize(port.getPin1()); - } - - @Override - public String getName() { - return "Magnetic"; - } - } -} - - diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/I2CSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/I2CSensor.java deleted file mode 100644 index e7344d1..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/I2CSensor.java +++ /dev/null @@ -1,293 +0,0 @@ -package lejos.hardware.sensor; - -import java.lang.IllegalArgumentException; - -import lejos.hardware.port.I2CException; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - -/** - * Class that implements common methods for all I2C sensors. - * - * Extend this class to implement new I2C sensors. - * - * TODO: We should probably change this class to use the Product ID etc. obtained - * by the Lego kernel module during initialisation. - * - * @author Lawrie Griffiths (lawrie.griffiths@ntlworld.com) and Andy Shaw. - * - */ -public class I2CSensor extends BaseSensor implements SensorConstants { - /** - * Register number of sensor version string, as defined by standard Lego I2C register layout. - * @see #getVersion() - */ - protected static final byte REG_VERSION = 0x00; - /** - * Register number of sensor vendor ID, as defined by standard Lego I2C register layout. - * @see #getVendorID() - */ - protected static final byte REG_VENDOR_ID = 0x08; - /** - * Register number of sensor product ID, as defined by standard Lego I2C register layout. - * @see #getProductID() - */ - protected static final byte REG_PRODUCT_ID = 0x10; - - protected static final int DEFAULT_I2C_ADDRESS = 0x02; - - protected I2CPort port; - protected int address; - private byte[] ioBuf = new byte[32]; - protected int retryCount = 3; - - /** - * Create the sensor using an already open sensor port. Do not configure the hardware - * @param port the open port - * @param address I2C address - */ - public I2CSensor(I2CPort port, int address) - { - this.port = port; - this.address = address; - } - - public I2CSensor(I2CPort port) - { - this(port, DEFAULT_I2C_ADDRESS); - } - - /** - * Create the sensor using the specified port. Configure the hardware as required. - * @param port port the sensor is attached to - * @param address I2C address - * @param type type of I2C sensor - */ - public I2CSensor(Port port, int address, int type) - { - this(port.open(I2CPort.class), address); - if (!this.port.setType(type)) - { - this.port.close(); - throw new IllegalArgumentException("Invalid sensor mode"); - } - releaseOnClose(this.port); - } - - public I2CSensor(Port port) - { - this(port, DEFAULT_I2C_ADDRESS, TYPE_LOWSPEED); - } - - public I2CSensor(Port port, int address) - { - this(port, address, TYPE_LOWSPEED); - } - - /** - * Set the number of times that a get/send data request should be retried. - * @param newCount number of times to try the request - */ - public void setRetryCount(int newCount) - { - if (newCount <= 0) - throw new IllegalArgumentException("Invalid retry count"); - retryCount = newCount; - } - - /** - * Return the current get/send retry count value - * @return current retry count - */ - public int getRetryCount() - { - return retryCount; - } - - /** - * Executes an I2C read transaction and waits for the result. - * - * @param register I2C register, e.g 0x41 - * @param buf Buffer to return data - * @param len Length of the return data - */ - public void getData(int register, byte [] buf, int len) { - getData(register, buf, 0, len); - } - - /** - * Executes an I2C read transaction and waits for the result. - * - * @param register I2C register, e.g 0x41 - * @param buf Buffer to return data - * @param offset Offset of the start of the data - * @param len Length of the return data - */ - public synchronized void getData(int register, byte [] buf, int offset, int len) { - // need to write the internal address. - ioBuf[0] = (byte)register; - I2CException error = null; - for(int i = 0; i < retryCount; i++) - { - try { - port.i2cTransaction(address, ioBuf, 0, 1, buf, offset, len); - return; - } - catch (I2CException e) - { - error = e; - } - } - throw error; - } - - /** - * Executes an I2C write transaction. - * - * @param register I2C register, e.g 0x42 - * @param buf Buffer containing data to send - * @param len Length of data to send - */ - public void sendData(int register, byte [] buf, int len) { - sendData(register, buf, 0, len); - } - - /** - * Executes an I2C write transaction. - * - * @param register I2C register, e.g 0x42 - * @param buf Buffer containing data to send - * @param offset Offset of the start of the data - * @param len Length of data to send - */ - public synchronized void sendData(int register, byte [] buf, int offset, int len) { - if (len >= ioBuf.length) - throw new IllegalArgumentException("Invalid buffer length"); - ioBuf[0] = (byte)register; - // avoid NPE in case length==0 and data==null - if (buf != null) - System.arraycopy(buf, offset, ioBuf, 1, len); - I2CException error = null; - for(int i = 0; i < retryCount; i++) - { - try { - port.i2cTransaction(address, ioBuf, 0, len+1, null, 0, 0); - return; - } - catch (I2CException e) - { - error = e; - } - } - throw error; - } - - /** - * Executes an I2C write transaction. - * - * @param register I2C register, e.g 0x42 - * @param value single byte to send - */ - public synchronized void sendData(int register, byte value) { - ioBuf[0] = (byte)register; - ioBuf[1] = value; - sendData(register, null, 0, 1); - } - - /** - * Read the sensor's version string. - * This method reads up to 8 bytes - * and returns the characters before the zero termination byte. - * Examples: "V1.0", ... - * - * @return version number - */ - public String getVersion() { - return fetchString(REG_VERSION, 8); - } - - /** - * Read the sensor's vendor identifier. - * This method reads up to 8 bytes - * and returns the characters before the zero termination byte. - * Examples: "LEGO", "HiTechnc", ... - * - * @return vendor identifier - */ - public String getVendorID() { - return fetchString(REG_VENDOR_ID, 8); - } - - /** - * Read the sensor's product identifier. - * This method reads up to 8 bytes - * and returns the characters before the zero termination byte. - * Examples: "Sonar", ... - * - * @return product identifier - */ - public String getProductID() { - return fetchString(REG_PRODUCT_ID, 8); - } - - /** - * Read a string from the device. - * This functions reads the specified number of bytes - * and returns the characters before the zero termination byte. - * - * @param reg - * @param len maximum length of the string, including the zero termination byte - * @return the string containing the characters before the zero termination byte - */ - protected String fetchString(byte reg, int len) { - byte[] buf = new byte[len]; - try - { - getData(reg, buf, 0, len); - } - catch (I2CException e) - { - return ""; - } - int i; - char[] charBuff = new char[len]; - for (i=0; iMindSensors Pressure Sensor
    - * This sensor measures pressures produced by LEGO Pneumatics systems and lot more! - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    PressureMeasures the absolute pressurePascal {@link #getPressureMode() }
    - * - * - *

    - * Sensor configuration
    - * Description of default sensor configuration (when that matters). Description - * of available methods for configuration. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author fussel_dlx - * - */ -public class MindSensorsPressureSensor extends I2CSensor { - - /* - * Code contributed and tested by fussel_dlx on the forums: - * http://lejos.sourceforge.net/forum/viewtopic.php?f=6&t=4329 - * - * Comment: the sensor can pressure in various units. However, using those - * units results in a loss of precision. And furthermore, the conversion to PSI or - * whatever can be done in Java. The obvious advantage is, that float can be used. - */ - - private static final int ADDRESS = 0x18; - private final byte[] buf = new byte[4]; - - public MindSensorsPressureSensor(I2CPort port) { - // also works with high speed mode - super(port, ADDRESS); - init(); - } - - public MindSensorsPressureSensor(Port port) { - // also works with high speed mode - super(port, ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new PressureMode() }); - } - - /** - * Return a ample provider for pressure mode. Pressure is expressed in Pascal. - */ - public SensorMode getPressureMode() { - return getMode(0); - } - -private class PressureMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x53, buf, 0, 4); - sample[offset] = EndianTools.decodeIntLE(buf, 0); - } - - @Override - public String getName() { - return "Pressure"; - } -} -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAbsoluteIMU.java b/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAbsoluteIMU.java deleted file mode 100644 index 7d0db25..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAbsoluteIMU.java +++ /dev/null @@ -1,363 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.Calibrate; - -/** - * Mindsensors AbsoluteIMU
    - * Sensor interface for the Mindsensors AbsoluteIMU family of sensors. The - * AbsoluteIMU sensors combine gyro, accelerometer and compass sensors in - * various combinations in a single housing. This interface works with all - * AbsoluteIMU models, but not all modes will work with any particular model. - * - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    MagneticMeasures the strength of the magnetic field over three axes {@link #getMagneticMode() }
    CompassMeasures the orientation of the sensorDegrees, corresponding to the compass rose {@link #getCompassMode() }
    AngleMeasures the orientation of the sensorDegrees, corresponding to the right hand coordinate system {@link #getAngleMode() }
    AccelerationThe Acceleration mode measures the linear acceleration of the sensor over - * three axesMetres/second^2 {@link #getAccelerationMode() }
    RateThe Rate mode measures the angular speed of the sensor over three axesDegrees/second {@link #getRateMode() }
    - * - * - *

    - * - * Sensor configuration
    - * The gyro sensor of the AbsoluteIMU uses a filter to remove noise from - * the samples. The filter can be configured using the {@link #setGyroFilter } - * method.
    - * The compass sensor of the AbsoluteIMU can be calibrated to compensate for magnetical disturbances on the robot (soft iron - * calibration) using the {@link #startCalibration} and {@link #stopCalibration} - * methods.

    - * To calibrate Compass, mount it on your robot where it will be used and - * issue startCalibration method and then rotate AbsoluteIMU slowly along all - * three axes. (The Compass in AbsoluteIMU is a 3 axis compass, and hence - * needs to be turned along all three axes, and if it's mounted on your robot, - * the whole robot needs to rotate). Rotate one axis at a time, turn once in - * clock-wise direction completing at-least 360 degrees, and then turn it in - * anti-clock-wise direction, then go to next axis. Upon finishing turning - * along all axes, issue stopCalibration method. - * - * - *

    - * - * See Mindsensors IMU user guide"> Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Andy - * - */ -public class MindsensorsAbsoluteIMU extends I2CSensor implements SensorModes, - Calibrate { - /** The default I2C address of the sensor */ - public static final int DEFAULT_I2C_ADDRESS = 0x22; - protected static final int ACCEL_DATA = 0x45; - protected static final int COMPASS_DATA = 0x4b; - protected static final int MAG_DATA = 0x4d; - protected static final int GYRO_DATA = 0x53; - protected static final int COMMAND = 0x41; - protected static final int GYRO_FILTER = 0x5a; - protected static final byte SENSITIVITY_BASE = 0x31; - protected static final byte START_CALIBRATION = 0x43; - protected static final byte END_CALIBRATION = 0x63; - public static final int LOW = 0; - public static final int MEDIUM = 1; - public static final int HIGH = 2; - public static final int VERY_HIGH = 3; - static final float[] gyroScale = { 1.0f, 2.0f, 8.0f, 8.0f }; - static final float[] magneticToSI = { 1.0f / 1100f, - 1.0f / 1100f, 1.0f / 980f }; - static final float[] accelerationToSI = { -0.00981f, 0.00981f, - 0.00981f }; - protected ShortSensorMode accelMode; - protected ShortSensorMode magMode; - protected ShortSensorMode gyroMode; - protected ShortSensorMode compassMode; - protected ShortSensorMode angleMode; - - protected class ShortSensorMode implements SensorMode { - protected final String name; - protected final int sampleSize; - protected final float[] convert; - protected final int baseReg; - protected float[] scale; - protected byte[] buffer; - - /** - * Internal class to provide the sensor data. Handles obtaining the base - * data and converting it to suitable SI units. - * - * @param name - * mode name - * @param reg - * base register for the available samples - * @param sampleSize - * number of samples - * @param convert - * conversion factor to SI units - * @param scale - * scale factor needed for range adjustment - */ - protected ShortSensorMode(String name, int reg, int sampleSize, - float[] convert, float scale) { - this.name = name; - this.sampleSize = sampleSize; - this.convert = convert; - this.baseReg = reg; - this.scale = new float[sampleSize]; - setScale(scale); - buffer = new byte[sampleSize * 2]; - } - - protected ShortSensorMode(String name, int reg, int sampleSize, - float convert, float scale) { - this.convert = new float[sampleSize]; - for (int i = 0; i < sampleSize; i++) - this.convert[i] = convert; - this.name = name; - this.sampleSize = sampleSize; - this.baseReg = reg; - this.scale = new float[sampleSize]; - setScale(scale); - buffer = new byte[sampleSize * 2]; - } - - /** - * Set the scale factor used when converting data to returned units. - * - * @param scale - * new scale factor - */ - protected void setScale(float scale) { - for (int i = 0; i < convert.length; i++) - this.scale[i] = convert[i] * scale; - } - - @Override - public int sampleSize() { - return sampleSize; - } - - @Override - public void fetchSample(float[] sample, int offset) { - // fetch the raw data - getData(baseReg, buffer, 0, buffer.length); - for (int i = 0; i < sampleSize; i++) { - int rawVal = (buffer[i * 2] & 0xff) | ((buffer[i * 2 + 1]) << 8); - sample[i + offset] = rawVal * scale[i]; - } - } - - @Override - public String getName() { - return name; - } - - } - - protected void init() { - // The accelerometer reports readings in mG we convert this to m/s/s - // TODO: we switch X axis direction to match dexter device. Do we need to do - // anything with the gyro etc? - accelMode = new ShortSensorMode("Acceleration", ACCEL_DATA, 3, - accelerationToSI, 1.0f); - // the magnetometer reports in Gauss - magMode = new ShortSensorMode("Magnetic", MAG_DATA, 3, magneticToSI, 1.0f); - // the gyro reports in units of 8.75 milli-degree/s we convert to degree/s - gyroMode = new ShortSensorMode("Rate", GYRO_DATA, 3, 0.00875f, 1.0f); - // the compass reports the angle in degrees. - compassMode = new ShortSensorMode("Compass", COMPASS_DATA, 1, 1.0f, 1.0f); - angleMode = new ShortSensorMode("Angle", COMPASS_DATA, 1, 1.0f, -1.0f); - this.setModes(new SensorMode[] { magMode, compassMode, angleMode, - accelMode, gyroMode }); - setRange(LOW); - setGyroFilter(4); - } - - public MindsensorsAbsoluteIMU(I2CPort port, int address) { - super(port, address); - init(); - - } - - public MindsensorsAbsoluteIMU(I2CPort port) { - this(port, DEFAULT_I2C_ADDRESS); - } - - public MindsensorsAbsoluteIMU(Port port, int address) { - super(port, address); - init(); - } - - public MindsensorsAbsoluteIMU(Port port) { - this(port, DEFAULT_I2C_ADDRESS); - } - - /** - * Return a SensorMode object that will provide tilt compensated compass data - * . The sample contains one element containing the bearing of the sensor - * relative to north expressed in degrees. East being at 90 degrees. - * - * @return a SensorMode object - */ - public SensorMode getCompassMode() { - return getMode(1); - } - - /** - * Return a SensorMode object that will provide angle data. The sample - * contains one element containing the bearing of the sensor relative to north - * expressed in degrees using a right hand coordinate system in the range of - * (-180 to 180). West being at 90 degrees, east being at -90 degrees. - * - * @return a SensorMode object - */ - public SensorMode getAngleMode() { - return getMode(2); - } - - /** - * Return a SensorMode object that will acceleration data for the X, Y and Z - * axis. The data is returned in units of m/s/s. - * - * @return a SensorMode object - */ - public SensorMode getAccelerationMode() { - return getMode(3); - } - - /** - * Return a SensorMode object that will return Magnetic data for the X, Y and - * Z axis The data is returned in Guass - * - * @return a SensorMode object - */ - public SensorMode getMagneticMode() { - return getMode(0); - } - - /** - * Return a SensorMode object that will angular velocity data for the X, Y and - * Z axis. The data is returned in units of degrees/s. - * - * @return a SensorMode object - */ - public SensorMode getRateMode() { - return getMode(4); - } - - /** - * Set the sensitivity used by the sensor. This setting impacts the maximum - * range of the returned value and the resolution of the reading.
    - * LOW Acceleration 2G Gyro 250 degrees/second
    - * MEDIUM Acceleration 4G Gyro 500 degrees/second
    - * HIGH Acceleration 8G Gyro 2000 degrees/second
    - * VERY_HIGH Acceleration 16G Gyro 2000 degrees/second
    - * The default setting is LOW. - * - * @param range - * the selected range (LOW/MEDIUM/HIGH/VERY_HIGH) - */ - public void setRange(int range) { - byte cmd = SENSITIVITY_BASE; - switch (range) { - case LOW: - case MEDIUM: - case HIGH: - case VERY_HIGH: - break; - default: - throw new IllegalArgumentException("Range setting invalid"); - } - cmd += range; - sendData(COMMAND, cmd); - // update gyro scale to match new setting - gyroMode.setScale(gyroScale[range]); - } - - /** - * Set the smoothing filter for the gyro.
    - * The Gyro readings are filtered with n’th order finite impulse response - * filter, (where n ranges from 0 to 7) value 0 will apply no filter, - * resulting in faster reading, but noisier values.value 7 will apply stronger - * filter resulting in slower read (about 10 milli-seconds slower) but less - * noise.
    - * The default value for the filter is 4. - * - * @param value - * (range 0-7) - */ - public void setGyroFilter(int value) { - sendData(GYRO_FILTER, (byte) value); - } - - /** - * To calibrate Compass, mount it on your robot where it will be used and - * issue startCalibration method and then rotate AbsoluteIMU slowly along all - * three axes. (The Compass in AbsoluteIMU is a 3 axis compass, and hence - * needs to be turned along all three axes, and if it's mounted on your robot, - * the whole robot needs to rotate). Rotate one axis at a time, turn once in - * clock-wise direction completing at-least 360 degrees, and then turn it in - * anti-clock-wise direction, then go to next axis. Upon finishing turning - * along all axes, issue stopCalibration method. - */ - @Override - public void startCalibration() { - sendData(COMMAND, START_CALIBRATION); - } - - /** - * Ends calibration sequence. - * - */ - @Override - public void stopCalibration() { - sendData(COMMAND, START_CALIBRATION); - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAccelerometer.java b/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAccelerometer.java deleted file mode 100644 index f9cb7a8..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsAccelerometer.java +++ /dev/null @@ -1,164 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.EndianTools; - - -/** - * Mindsensors acceleration (tilt) sensor ACCL-Nx-v2/v3
    - * The Mindsensors Accelerometer Sensor measures acceleration or tilt in three - * axes. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    AccelerationMeasures acceleration over three axes.meter / second2 {@link #getAccelerationMode() }
    TiltMeasures tilt over three axes.degrees2 {@link #getTiltMode() }
    - * - * - *

    - * - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class MindsensorsAccelerometer extends I2CSensor { - private static final byte BASE_TILT = 0x42; - private static final byte BASE_ACCEL = 0x45; - private static final byte OFF_X_ACCEL = 0x00; - private static final byte OFF_Y_ACCEL = 0x02; - private static final byte OFF_Z_ACCEL = 0x04; - private static final float TO_SI = 0.00980665f; - - private byte[] buf = new byte[6]; - - /** - * Creates a SampleProvider for the Mindsensors ACCL-Nx - * - * @param port the I2C port - * @param address the I2C address of the sensor - */ - public MindsensorsAccelerometer(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Creates a SampleProvider for the Mindsensors ACCL-Nx - * - * @param port the I2C port - */ - public MindsensorsAccelerometer(I2CPort port) { - super(port); - init(); - } - - /** - * Creates a SampleProvider for the Mindsensors ACCL-Nx - * - * @param port the sensor port - * @param address the I2C address of the sensor - */ - public MindsensorsAccelerometer(Port port, int address) { - super(port, address, TYPE_LOWSPEED_9V); - init(); - } - - /** - * Creates a SampleProvider for the Mindsensors ACCL-Nx - * - * @param port the sensor port - */ - public MindsensorsAccelerometer(Port port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new AccelMode(), new TiltMode() }); - } - - private class AccelMode implements SensorMode { - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(BASE_ACCEL, buf, 0, 6); - sample[offset+0] = EndianTools.decodeShortLE(buf, OFF_X_ACCEL) * TO_SI; - sample[offset+1] = EndianTools.decodeShortLE(buf, OFF_Y_ACCEL) * TO_SI; - sample[offset+2] = -EndianTools.decodeShortLE(buf, OFF_Z_ACCEL) * TO_SI; - } - - - @Override - public String getName() { - return "Acceleration"; - } - } - - /** - * Return a SampleProvider that provides acceleration data (in m/s/s) in X, Y, Z axis - */ - public SensorMode getAccelerationMode() { - return getMode(0); - } - - /** - * Return a SampleProvider that provides tilt data (in degree) in X, Y, Z axis - */ - public SensorMode getTiltMode() { - return getMode(1); - } - - private class TiltMode implements SensorMode { - private float toSI=180f/128f; - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(BASE_TILT, buf, 0, 3); - sample[offset+0] = ((buf[0] & 0xFF) - 128.0f)*toSI; - sample[offset+1] = ((buf[1] & 0xFF) - 128.0f)*toSI; - sample[offset+2] = ((buf[2] & 0xFF) - 128.0f)*toSI; - } - - @Override - public String getName() { - return "Tilt"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsBTSense.java b/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsBTSense.java deleted file mode 100644 index 9e4682c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsBTSense.java +++ /dev/null @@ -1,501 +0,0 @@ -package lejos.hardware.sensor; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.Map; - -import lejos.hardware.Bluetooth; -import lejos.hardware.sensor.SensorMode; -import lejos.remote.nxt.NXTCommConnector; -import lejos.remote.nxt.NXTConnection; - -/** - * Support for the Mindsensors BTSense application - * - * @author Lawrie Griffiths - * - */ -public class MindsensorsBTSense { - private int trId = 0; - private InputStream is; - private OutputStream os; - private byte[] reply = new byte[512]; - private int currLen = 0; - private int packets = 0; - private boolean debug = true; - - /** - * A - Accelerometer - * G - Gravity - * N - Linear Acceleration - * L - Light - * M - Magnetic Field - * C - Compass - * P - Proximity - * S - Sound - * D - Date - * T - Time - * G - Gyroscope - * E - Atmospheric pressure - * H - Humidity - * U - Temperature - * W - Network location - * O - GPS Location - */ - private Map modes = new HashMap(); - - /** - * Connection to the BTSense application and identify device as EV3 - * @throws IOException - */ - public MindsensorsBTSense() throws IOException { - NXTCommConnector connector = Bluetooth.getNXTCommConnector(); - - if (debug) System.out.println("Waiting for connection ..."); - NXTConnection con = connector.waitForConnection(0, NXTConnection.RAW); - System.out.println("Connected"); - - is = con.openInputStream(); - os = con.openOutputStream(); - - if (debug) System.out.println("Sending Identify command"); - sendCmd("@:xIE"); - - // Start a background thread to read data from phone and put it in the relevant sensor mode - new DataReader().start(); - } - - /** - * Get a SensorMode object for a specific sensor mode and request data from phone - * - * @param sensorType the single character sensor mode identifier - * @return the SensorMode implementation - * @throws IOException - * @throws InterruptedException - */ - public SensorMode getSensorMode(char sensorType) throws IOException, InterruptedException { - BTSenseMode mode = modes.get(sensorType); - - if (mode == null) { - sendCmd("+:t" + sensorType + "1"); // Currently everything is priority 1 - return new BTSenseMode(sensorType, modes); - } else { - return mode; - } - } - - /** - * Send a command to the phone application, with a transaction id - * @param cmd - * @throws IOException - */ - public void sendCmd(String cmd) throws IOException { - byte[] b = new byte[cmd.length()+2]; - b[0] = (byte) (cmd.length()); - b[1] = 0; - System.arraycopy(cmd.getBytes(), 0, b, 2, cmd.length()); - b[4] = (byte) trId++; - - os.write(b, 0, cmd.length()+2); - os.flush(); - } - - // Read the reply into the reply buffer at specified offset - public int getReply(int offset) throws IOException { - //System.out.println("Reading data at offset " + offset); - return is.read(reply, offset, reply.length); - } - - /** - * Process data from the phone application - * @throws IOException - */ - public void processData() throws IOException { - int len = 0; - - while(true) { - if (currLen == 0) { - len = getReply(0); - if (debug) System.out.println("Received " + len + " bytes "); - if (len <= 0) return; - currLen = len; - } - - int packetLength = reply[0]; - //System.out.println("Packet length = " + packetLength); - - if (packetLength > currLen - 1) { - len = getReply(currLen); - if (debug) System.out.println("Received extra " + len + " bytes "); - if (len <= 0) return; - currLen += len; - } - - //printReply(); - - byte [] packet = new byte[packetLength]; - System.arraycopy(reply, 1, packet, 0, packetLength); - packets++; - extractData(packet); - - System.arraycopy(reply, packetLength+1, reply, 0, currLen - (packetLength + 1)); - currLen -= (packetLength + 1); - } - } - - // Diagnostic method to print the reply data in hex - private void printReply() { - // Print the current data - for(int i=0;i sampleSizes = new HashMap(); - - static { - sampleSizes.put('A', 3); - sampleSizes.put('R', 3); - sampleSizes.put('N', 3); - sampleSizes.put('L', 1); - sampleSizes.put('A', 3); - sampleSizes.put('M', 3); - sampleSizes.put('P', 1); - sampleSizes.put('C', 3); - sampleSizes.put('S', 1); - sampleSizes.put('D', 3); - sampleSizes.put('T', 3); - sampleSizes.put('G', 3); - sampleSizes.put('E', 1); - sampleSizes.put('H', 1); - sampleSizes.put('U', 1); - sampleSizes.put('W', 2); - sampleSizes.put('O', 6); - } - - BTSenseMode(char sensorType, Map modes) throws InterruptedException { - this.sensorType = sensorType; - sampleSize = sampleSizes.get(sensorType); - latest = new float[sampleSize]; - modes.put(sensorType, this); - synchronized(this) { - wait(); - } - } - - @Override - public int sampleSize() { - return sampleSize; - } - - @Override - public void fetchSample(float[] sample, int offset) { - for(int i=0;iMindsensors compass sensor. - * - * See http://www.mindsensors.com/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=56 - * - * author Lawrie Griffiths - * - */ -/** - * MindSensor Compass sensor
    - * Description - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    CompassMeasures the orientation of the sensorDegrees, corresponding to the compass rose {@link #getCompassMode() }
    AngleMeasures the orientation of the sensorDegrees, corresponding to the right hand coordinate system {@link #getAngleMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be calibrated for magnetic disturbances coming from the robot - * (soft iron calibration). Use the startCalibration method to put the sensor in - * calibration mode. While in calibration mode the sensor should be rotated - * slowly for making 2 full rotations taking at least 20 seconds per turn. Then - * end calibration with the endCalibration method. - *

    - * - * See - * Sensor datasheet - * See - * Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class MindsensorsCompass extends I2CSensor implements Calibrate { - private final static byte COMMAND = 0x41; - private final static byte BEGIN_CALIBRATION = 0x43; - private final static byte END_CALIBRATION = 0x44; - - private byte[] buf = new byte[2]; - - /** - * Create a compass sensor object - * - * @param port - * I2C port for the compass - * @param address - * The I2C address used by the sensor - */ - public MindsensorsCompass(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * I2C port for the compass - */ - public MindsensorsCompass(I2CPort port) { - super(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * Sensor port for the compass - * @param address - * The I2C address used by the sensor - */ - public MindsensorsCompass(Port port, int address) { - super(port, address); - init(); - } - - /** - * Create a compass sensor object - * - * @param port - * Sensor port for the compass - */ - public MindsensorsCompass(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new CompassMode(), new AngleMode() }); - } - - /** - * Mindsensors compass sensor, Compass mode
    - * Measures the bearing of the sensor. * - *

    - * Size and content of the sample
    - * The sample contains one element containing the bearing of the sensor - * relative to north expressed in degrees. East being at 90 degrees. - */ - public SensorMode getCompassMode() { - return getMode(0); - } - - private class CompassMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 1); - - // TODO: Could use integer mode for higher resolution - sample[offset] = (255 - (buf[0] & 0xFF)) * 359f / 255f; - } - - @Override - public String getName() { - return "Compass"; - } - - } - - /** - * MindSensors compass sensor, Angle mode
    - * Measures the bearing of the sensor. - * - *

    - * Size and content of the sample
    - * The sample contains one element containing the bearing of the sensor - * relative to north expressed in degrees using a right hand coordinate system - * in the range of (-180 to 180). West being at 90 degrees, east being at -90 - * degrees. - */ - public SensorMode getAngleMode() { - return getMode(0); - } - - private class AngleMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x42, buf, 1); - - // TODO: Could use integer mode for higher resolution - sample[offset] = (255 - (buf[0] & 0xFF)) * -359f / 255f; - } - - @Override - public String getName() { - return "Angle"; - } - - } - - /** - * Starts calibration for the compass. Must rotate *very* slowly, taking at - * least 20 seconds per rotation. - * - * Should make 1.5 to 2 full rotations. Must call stopCalibration() when done. - */ - public void startCalibration() { - buf[0] = BEGIN_CALIBRATION; - sendData(COMMAND, buf, 1); - } - - /** - * Ends calibration sequence. - * - */ - public void stopCalibration() { - buf[0] = END_CALIBRATION; - sendData(COMMAND, buf, 1); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsDistanceSensorV2.java b/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsDistanceSensorV2.java deleted file mode 100644 index 0fb3363..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsDistanceSensorV2.java +++ /dev/null @@ -1,215 +0,0 @@ - package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.EndianTools; - - -/** - * Mindsensors DIST-Nx series of Optical Distance Sensors, Version 2
    - * Mindsensors DIST Sensor measure the distance to an object in front of the sensor using IR light - * - - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    DistanceMeasures distance to an object in front of the sensorMeter {@link #getDistanceMode() }
    VoltageReturns the output level of the sensors signal processing unitVolt {@link #getVoltageMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be powered on and off using the powerOn and powerOff methods. It is useful to power off the sensor when not in use as it consumes a a fair bit of energy. - *
    - * The sensor can be tuned for a particular Sharp optical distance sensor using the setModule method. See the top of the sensor for the Sharp module installed on the sensor. - *
    - * The sensor supports hardware calibration but this in not supported by this interface. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Michael Smith - * - */ -public class MindsensorsDistanceSensorV2 extends I2CSensor { - private byte[] buf = new byte[2]; - - //Registers - private final static int COMMAND = 0x41; - private final static int DIST_DATA_LSB = 0x42; - public static final int VOLT_DATA_LSB = 0x44; - - //Commands - private final static byte DE_ENERGIZED = 0x44; - private final static byte ENERGIZED = 0x45; - private final static byte GP2D12 = 0x31; - private final static byte GP2D120 = 0x32; - private final static byte GP2Y0A21YK = 0x33; - private final static byte GP2Y0A02YK = 0x34; - private final static byte CUSTOM_MODULE = 0x31; - - - - /** - * - * @param port NXT sensor port 1-4 - */ - public MindsensorsDistanceSensorV2(I2CPort port){ - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * - * @param port NXT sensor port 1-4 - * @param address I2C address for the sensor - */ - public MindsensorsDistanceSensorV2(I2CPort port, int address){ - super(port, address); - init(); - } - - /** - * - * @param port NXT sensor port 1-4 - */ - public MindsensorsDistanceSensorV2(Port port){ - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * - * @param port NXT sensor port 1-4 - * @param address I2C address for the sensor - */ - public MindsensorsDistanceSensorV2(Port port, int address){ - super(port, address, TYPE_LOWSPEED); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new DistanceMode(), new VoltageMode() }); - powerOn(); - } - - /** - * Turns the sensor module on.
    - * Power is turned on by the constructor method. - * - */ - public void powerOn(){ - sendData(COMMAND, ENERGIZED); - } - - /** - * Turns power to the sensor module off. - * - */ - public void powerOff(){ - sendData(COMMAND, DE_ENERGIZED); - } - - - /** Configure the sensor for a particular Sharp Module - * @param module See static fields for valid modules - */ - public void setModule (byte module) { - if (module <0x31 || module > 0x35 ) { - throw new IllegalArgumentException(); - } - else { - sendData(COMMAND, module); - } - } - - /** - * Returns a sample provider that measures distance (in meter). - */ - public SensorMode getDistanceMode() { - return getMode(0); - } - - - //TODO: I think it is milivolt and should be converted to volt (Aswin) - /** - * Returns a sample provider that measures the output level (in volt) of the sensors signal processing unit. - */ - public SensorMode getVoltageMode() { - return getMode(1); - } - -private class DistanceMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DIST_DATA_LSB, buf, 2); - sample[offset] = (float) EndianTools.decodeShortLE(buf, 0) / 100f; - } - - @Override - public String getName() { - return "Distance"; - } - - -} - - private void dump() { - System.out.print(buf.length+": "); - for (int i=0;iMindSensors Light Senor Array
    - * This sensor an array of 8 sensors with controlled light source, returning you values of the sensor readings. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RedMeasures the light value when illuminated with a red light source.N/A, normalized {@link #getRedMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be calibrated for black and white using the calibrateWhite and calibrateBlack methods.

    - * The sensor can be put in and out of sleep mode (lights off) using the sleep method and wakeUp methods. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Juan Antonio Brenha Moral, Eric Pascual (EP) - * - */ -public class MindsensorsLightSensorArray extends I2CSensor { - private byte[] buf = new byte[8]; - private final static byte COMMAND = 0x41; - private final static byte DATA = 0x42; - private final static int FACTORY_DEFAULT = 0x14; - - //TODO in addition to the calibrates values, the driver should also provide - // access to the RAW values at 0x6A to 0x79 (2 byte per sensor) so that - // calibration can be performed with the leJOS filter framework. - - /** - * Constructor - * - * @param port - * @param address I2C address for the device - */ - public MindsensorsLightSensorArray(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Constructor - * - * @param port - */ - public MindsensorsLightSensorArray(I2CPort port) { - this(port, FACTORY_DEFAULT); - init(); - } - - /** - * Constructor - * - * @param port - * @param address I2C address for the device - */ - public MindsensorsLightSensorArray(Port port, int address) { - super(port, address, TYPE_LOWSPEED); - init(); - } - - /** - * Constructor - * - * @param port - */ - public MindsensorsLightSensorArray(Port port) { - this(port, FACTORY_DEFAULT); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new LightArrayMode() }); - } - - /** - * Send a single byte command represented by a letter - * - * @param cmd the command to be sent - */ - public void sendCommand(char cmd) { - sendData(COMMAND, (byte) cmd); - } - - /** - * Sleep the sensor - */ - public void sleep() { - sendCommand('D'); - } - - /** - * Wake up the sensor - * - */ - public void wakeUp() { - sendCommand('P'); - } - - public void calibrateWhite() { - sendCommand('W'); - } - - public void calibrateBlack() { - sendCommand('B'); - } - - /** - * Return a sample provider in that measures the light reflection of a surface illuminated with a red led light. The sensor houses 8 light sensors. Each element in the sample represents one light sensor. - */ - public SensorMode getRedMode() { - return getMode(0); - } - - private class LightArrayMode implements SensorMode { - @Override - public int sampleSize() { - return 8; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(DATA,buf,8); - - for(int i=0;i<8;i++) { - sample[offset+i] = buf[i]/100f; - } - } - - @Override - public String getName() { - return "Red"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsLineLeader.java b/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsLineLeader.java deleted file mode 100644 index 4e61304..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/MindsensorsLineLeader.java +++ /dev/null @@ -1,165 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - -/** - * MindSensors Line Follower Sensor
    - * This sensor an array of 8 sensors with controlled light source, returning you values of the sensor readings. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RedMeasures the light value when illuminated with a red light source.N/A, normalized {@link #getRedMode() }
    - * - * - *

    - * Sensor configuration
    - * The sensor can be calibrated for black and white using the calibrateWhite and calibrateBlack methods.

    - * The sensor can be put in and out of sleep mode (lights off) using the sleep method and wakeUp methods. - * - *

    - * - * See Sensor datasheet - * See Sensor Product page - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Juan Antonio Brenha Moral, Eric Pascual (EP) - * - */ -public class MindsensorsLineLeader extends I2CSensor { - private byte[] buf = new byte[8]; - private final static byte COMMAND = 0x41; - - /** - * Constructor - * - * @param port - * @param address I2C address for the device - */ - public MindsensorsLineLeader(I2CPort port, int address) { - super(port, address); - init(); - } - - /** - * Constructor - * - * @param port - */ - public MindsensorsLineLeader(I2CPort port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - /** - * Constructor - * - * @param port - * @param address I2C address for the device - */ - public MindsensorsLineLeader(Port port, int address) { - super(port, address, TYPE_LOWSPEED_9V); - init(); - } - - /** - * Constructor - * - * @param port - */ - public MindsensorsLineLeader(Port port) { - this(port, DEFAULT_I2C_ADDRESS); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new RedMode() }); - } - - /** - * Send a single byte command represented by a letter - * - * @param cmd the command to be sent - */ - public void sendCommand(char cmd) { - sendData(COMMAND, (byte) cmd); - } - - /** - * Sleep the sensor - */ - public void sleep() { - sendCommand('D'); - } - - /** - * Wake up the sensor - * - */ - public void wakeUp() { - sendCommand('P'); - } - - public void calibrateWhite() { - sendCommand('W'); - } - - public void calibrateBlack() { - sendCommand('B'); - } - - /** - * Return a sample provider in that measures the light reflection of a surface illuminated with a red led light. The sensor houses 8 light sensors. Each element in the sample represents one light sensor. - */ - public SensorMode getRedMode() { - return getMode(0); - } - - private class RedMode implements SensorMode { - @Override - public int sampleSize() { - return 8; - } - - @Override - public void fetchSample(float[] sample, int offset) { - getData(0x49,buf,8); - - for(int i=0;i<8;i++) { - sample[offset+i] = buf[i]/100; - } - } - - @Override - public String getName() { - return "Red"; - } - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/NXTColorSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/NXTColorSensor.java deleted file mode 100644 index 31e2432..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/NXTColorSensor.java +++ /dev/null @@ -1,319 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.*; - -/** - * LEGO NXT Color Sensor
    - * allows the reading of - * raw color values. The sensor has a tri-color LED and this can - * be set to output red/green/blue or off. It also has a full mode in which - * four samples are read (off/red/green/blue) very quickly. These samples can - * then be combined using the calibration data provided by the device to - * determine the "LEGO" color currently being viewed. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    Color IDMeasures the color IDColor ID {@link #getColorIDMode() }
    RedMeasures the light value when illuminated with a red light source.N/A, normalized {@link #getRedMode() }
    GreenMeasures the light value when illuminated with a green light source.N/A, normalized {@link #getGreenMode() }
    BlueMeasures the light value when illuminated with a blue light source.N/A, normalized {@link #getBlueMode() }
    RGBMeasures the light value when illuminated with a white light source.N/A, normalized {@link #getRGBMode}
    AmbientMeasures the light value of ambient light.N/A, normalized {@link #getAmbientMode() }
    - * - * - *

    - * - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Andy - * - */ - -public class NXTColorSensor extends AnalogSensor implements SensorConstants, LampController, ColorIdentifier -{ - protected static final long SWITCH_DELAY = 10; - protected static int[] colorMap = - { - -1, Color.BLACK, Color.BLUE, Color.GREEN, Color.YELLOW, Color.RED, Color.WHITE - }; - private float[] ADRaw = new float[5]; - - private class ModeProvider implements SensorMode - { - final String name; - final int type; - final int sampleSize; - final int startOffset; - - ModeProvider(String name, int typ, int sz, int offset) - { - this.name = name; - type = typ; - sampleSize = sz; - startOffset = offset; - } - - @Override - public int sampleSize() - { - return sampleSize; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - switchType(type, SWITCH_DELAY); - readRaw(); - // return normalized values - //TODO: Is this the correct way to normalize this output? - // Normalize to 3.3 the ref voltage on pin 6 on the NXT - for(int i = 0; i < sampleSize; i++) - sample[offset+i] = (float)ADRaw[startOffset+i]/3.3f; - } - - @Override - public String getName() - { - return name; - } - - } - - protected void init() - { - setModes(new SensorMode[]{new ColorIDMode(), - new ModeProvider("Red", TYPE_COLORRED, 1, 0), - new ModeProvider("Green", TYPE_COLORGREEN, 1, 1), - new ModeProvider("Blue", TYPE_COLORBLUE, 1, 2), - new ModeProvider("RGB", TYPE_COLORFULL, 4, 0), - new ModeProvider("None", TYPE_COLORNONE, 1, 3) }); - setFloodlight(Color.WHITE); - } - - - /** - * Create a new Color Sensor instance and bind it to a port. - * @param port Port to use for the sensor. - */ - public NXTColorSensor(AnalogPort port) - { - super(port); - init(); - } - - /** - * Create a new Color Sensor instance and bind it to a port. - * @param port Port to use for the sensor. - */ - public NXTColorSensor(Port port) - { - super(port); - init(); - } - - - /** - * get a sample provider in color ID mode - * @return the sample provider - */ - public SensorMode getColorIDMode() - { - return getMode(0); - } - - /** - * get a sample provider the returns the light value when illuminated with a - * Red light source. - * @return the sample provider - */ - public SensorMode getRedMode() - { - return getMode(1); - } - - /** - * get a sample provider the returns the light value when illuminated with a - * Green light source. - * @return the sample provider - */ - public SensorMode getGreenMode() - { - return getMode(2); - } - - /** - * get a sample provider the returns the light value when illuminated with a - * Blue light source. - * @return the sample provider - */ - public SensorMode getBlueMode() - { - return getMode(3); - } - - /** - * get a sample provider the returns the light values (RGB + ambient) when illuminated by a - * white light source. - * @return the sample provider - */ - public SensorMode getRGBMode() - { - return getMode(4); - } - - /** - * get a sample provider the returns the light value when illuminated without a - * light source. - * @return the sample provider - */ - public SensorMode getAmbientMode() - { - return getMode(5); - } - - protected void readRaw() - { - port.getFloats(ADRaw, 0, ADRaw.length-1); - } - - protected void readFull() - { - port.getFloats(ADRaw, 0, ADRaw.length); - } - - public void setFloodlight(boolean floodlight) - { - setFloodlight(floodlight ? Color.RED : Color.NONE); - } - - - public int getFloodlight() - { - switch(currentType) - { - case TYPE_COLORFULL: - return Color.WHITE; - case TYPE_COLORRED: - return Color.RED; - case TYPE_COLORGREEN: - return Color.GREEN; - case TYPE_COLORBLUE: - return Color.BLUE; - case TYPE_COLORNONE: - return Color.NONE; - default: - throw new IllegalStateException("Unknown color type" + currentType); - } - } - - public boolean isFloodlightOn() - { - return (getFloodlight() != Color.NONE); - } - - public boolean setFloodlight(int color) - { - switch (color) - { - case Color.RED: - switchType(NXTColorSensor.TYPE_COLORRED, SWITCH_DELAY); - break; - case Color.BLUE: - switchType(NXTColorSensor.TYPE_COLORBLUE, SWITCH_DELAY); - break; - case Color.GREEN: - switchType(NXTColorSensor.TYPE_COLORGREEN, SWITCH_DELAY); - break; - case Color.NONE: - switchType(NXTColorSensor.TYPE_COLORNONE, SWITCH_DELAY); - break; - case Color.WHITE: - switchType(NXTColorSensor.TYPE_COLORFULL, SWITCH_DELAY); - break; - default: - return false; - } - return true; - } - - /** - * Read the current color and return an enumeration constant. This is usually only accurate at a distance - * of about 1 cm. - * @return The color id under the sensor. - */ - public int getColorID() - { - switchType(TYPE_COLORFULL, SWITCH_DELAY); - readFull(); - return colorMap[(int)ADRaw[BLANK_INDEX+1]]; - } - - private class ColorIDMode implements SensorMode{ - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - sample[offset] = (float) getColorID(); - } - - - @Override - public String getName() - { - return "ColorID"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/NXTLightSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/NXTLightSensor.java deleted file mode 100644 index 0231250..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/NXTLightSensor.java +++ /dev/null @@ -1,166 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.Color; -import lejos.robotics.LampController; - - -/** - * LEGO NXT light Sensor
    - * The NXT light sensor measures light levels of reflected or ambient light. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RedMeasures the light value when illuminated with a red light source.N/A, normalized {@link #getRedMode() }
    AmbientMeasures the light value of ambient light.N/A, normalized {@link #getAmbientMode() }
    - * - *

    - * See Mindstorms NXT HDK/SDK - * - */ -public class NXTLightSensor extends AnalogSensor implements LampController, SensorConstants -{ - protected static final long SWITCH_DELAY = 10; - private boolean floodlight = false; - - private class AmbientMode implements SensorMode - { - - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - setFloodlight(false); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() - { - return "Ambient"; - } - - } - protected void init() - { - setModes(new SensorMode[]{ new RedMode(), new AmbientMode() }); - setFloodlight(true); - } - - /** - * Create a light sensor object attached to the specified port. - * The sensor will be set to floodlight mode, i.e. the LED will be turned on. - * @param port port, e.g. Port.S1 - */ - public NXTLightSensor(AnalogPort port) - { - super(port); - init(); - } - - /** - * Create a light sensor object attached to the specified port. - * The sensor will be set to floodlight mode, i.e. the LED will be turned on. - * @param port port, e.g. Port.S1 - */ - public NXTLightSensor(Port port) - { - super(port); - init(); - } - - public void setFloodlight(boolean floodlight) - { - switchType(floodlight ? TYPE_LIGHT_ACTIVE : TYPE_LIGHT_INACTIVE, SWITCH_DELAY); - this.floodlight = floodlight; - } - - public boolean setFloodlight(int color) { - if(color == Color.RED) { - setFloodlight(true); - return true; - } else if (color == Color.NONE) { - setFloodlight(false); - return true; - } else return false; - } - - public int getFloodlight() { - if(this.floodlight == true) - return Color.RED; - else - return Color.NONE; - } - - public boolean isFloodlightOn() { - return this.floodlight; - } - - /** - * get a sample provider the returns the light value when illuminated with a - * Red light source. - * @return the sample provider - */ - public SensorMode getRedMode() - { - return getMode(0); - } - - /** - * get a sample provider the returns the light value when illuminated without a - * light source. - * @return the sample provider - */ - public SensorMode getAmbientMode() - { - return getMode(1); - } - - private class RedMode implements SensorMode { - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - setFloodlight(true); - sample[offset] = 1.0f - normalize(port.getPin1()); - - } - - @Override - public String getName() - { - return "Red"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/NXTSoundSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/NXTSoundSensor.java deleted file mode 100644 index 3975286..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/NXTSoundSensor.java +++ /dev/null @@ -1,134 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; - -/** - * NXT Sound sensor
    - * Description - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    dBAMeasures sound level adjusted to the sensitivity of the human earN/A, normalized {@link #getDBAMode() }
    dBMeasures sound levelN/A, normalized {@link #getDBMode() }
    - * - * - *

    - * - * See Mindstorms NXT HDK/SDK - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Lawrie Griffiths - * - */ -public class NXTSoundSensor extends AnalogSensor implements SensorConstants { - protected static final long SWITCH_DELAY = 10; - /** - * Create a sound sensor. - * - * @param port - * the sensor port to use - */ - public NXTSoundSensor(Port port) { - super(port); - init(); - } - - /** - * Create a sound sensor. - * - * @param port - * the sensor port to use - */ - public NXTSoundSensor(AnalogPort port) { - super(port); - init(); - } - - private void init() { - setModes(new SensorMode[]{ new DBAMode(), new DBMode() }); - } - - public class DBMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchType(TYPE_SOUND_DB, SWITCH_DELAY); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() { - return "Sound DB"; - } - - } - - - /** - * get a sample provider the returns the sound level - * @return the sample provider - */ - public SampleProvider getDBMode() { - return getMode(1); - } - - /** - * get a sample provider the returns the sound level adjusted to how a human ear would experience it - * @return the sample provider - */ - public SampleProvider getDBAMode() { - return getMode(0); - } - - private class DBAMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - switchType(TYPE_SOUND_DBA, SWITCH_DELAY); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() { - return "Sound DBA"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/NXTTouchSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/NXTTouchSensor.java deleted file mode 100644 index b85153a..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/NXTTouchSensor.java +++ /dev/null @@ -1,101 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - - -/** - * NXT Touch sensor
    - * A sensor that can be pressed like a button. Also works with RCX touch sensors. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    TouchDetects a press of the buttonboolean {@link #getTouchMode() }
    - * - *

    - * - * See Mindstorms NXT HDK/SDK - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - */ -public class NXTTouchSensor extends AnalogSensor implements SensorConstants -{ - - /** - * Create a touch sensor object attached to the specified open port. Note this - * port will not be configured. Any configuration od the sensor port must take - * place externally. - * @param port an open Analog port - */ - public NXTTouchSensor(AnalogPort port) - { - super(port); - port.setTypeAndMode(TYPE_SWITCH, MODE_RAW); - init(); - } - - /** - * Create an NXT touch sensor object attached to the specified port. - * @param port the port that has the sensor attached - */ - public NXTTouchSensor(Port port) - { - super(port); - this.port.setTypeAndMode(TYPE_SWITCH, MODE_RAW); - init(); - } - - protected void init() { - setModes(new SensorMode[]{new TouchMode()}); - } - - /** - * get a sample provider that returns an indication of the button being up(0) or down(1) - * @return the sample provider - */ - public SensorMode getTouchMode() - { - return getMode(0); - } - - - private class TouchMode implements SensorMode { - @Override - public int sampleSize() - { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) - { - sample[offset] = (port.getPin1() > EV3SensorConstants.ADC_REF/2f ? 0.0f : 1.0f); - } - - @Override - public String getName() - { - return "Touch"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/NXTUltrasonicSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/NXTUltrasonicSensor.java deleted file mode 100644 index a87b549..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/NXTUltrasonicSensor.java +++ /dev/null @@ -1,237 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.robotics.SampleProvider; -import lejos.utility.Delay; - -/** - * NXT Ultrasonic sensor
    - * The NXT Ultrasonic sensor generates sound waves and reads their echoes to detect and measure distance from objects. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    DistanceMeasures the distance to the nearest object in front of the sensormeter {@link #getDistanceMode() }
    PingMeasures the distance to the nearest 8 objects in front of the sensormeter {@link #getPingMode() }
    - * - *

    - * - * See Mindstorms NXT HDK/SDK - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Aswin - * - */ -public class NXTUltrasonicSensor extends I2CSensor { - // Supported modes - // According to the datasheet there are other modes. These modes do not function on the sensor and are not implemented; - protected static final byte MODE_OFF = 0x00; - protected static final byte MODE_PING = 0x01; - protected static final byte MODE_CONTINUOUS = 0x02; - - // Registers - private static final byte REG_MODE = 0x41; - private static final byte REG_DISTANCE = 0x42; - - // Timing values for the sensor - private static final int DELAY_CMD = 5; - private static final int DELAY_DATA_PING = 50; - private static final int DELAY_DATA_CONTINUOUS = 30; - - //multiplication factor to convert to SI unit meter. - private static final float TOSI=0.01f; - - private byte currentMode=0; - private byte[] byteBuff = new byte[8]; - private long nextCmdTime = 0; - private long dataAvailableTime; - - - /** - * Wait until the specified time - */ - private void waitUntil(long when) - { - long delay = when - System.currentTimeMillis(); - Delay.msDelay(delay); - } - - /* - * Over-ride standard get function to ensure correct inter-command timing - * when using the ultrasonic sensor. The Lego Ultrasonic sensor uses a - * "bit-banged" i2c interface and seems to require a minimum delay between - * commands otherwise the commands fail. - */ - @Override - public synchronized void getData(int register, byte[] buf, int off, int len) - { - waitUntil(nextCmdTime); - super.getData(register, buf, off, len); - nextCmdTime = System.currentTimeMillis() + DELAY_CMD; - } - - /* - * Over-ride the standard send function to ensure the correct inter-command - * timing for the ultrasonic sensor. - */ - @Override - public synchronized void sendData(int register, byte[] buf, int off, int len) - { - waitUntil(nextCmdTime); - super.sendData(register, buf, off, len); - nextCmdTime = System.currentTimeMillis() + DELAY_CMD; - } - - - - public NXTUltrasonicSensor(I2CPort port) { - super(port); - init(); - } - - public NXTUltrasonicSensor(Port port) { - super(port, DEFAULT_I2C_ADDRESS, TYPE_LOWSPEED_9V); - init(); - } - - private void init() { - setModes(new SensorMode[]{ new DistanceMode(), new PingMode()}); - nextCmdTime = System.currentTimeMillis() + DELAY_CMD; - setMode(MODE_CONTINUOUS); - dataAvailableTime = System.currentTimeMillis()+DELAY_DATA_CONTINUOUS; - - } - - /** Gives a SampleProvider representing the sensor in distance mode. - * In this mode the sensor scans the surrounding continuously and reports the distance to the nearest object in sight. - * The sensor reports the distance to the nearest object in meters. The theoretical range of the sensor is 0,04 to 2.54 meter. - * If there is no object detected within this range the sensor reports Float.POSITIVE_INFINITY.
    - * Samples can only be provided every 30 ms. If samples are fetched more often the SampleProvider will pause until the 30ms have passed. - * @return - * A SamplePrivider - */ - public SampleProvider getDistanceMode() { - return getMode(0); - } - - - /** Gives a SampleProvider representing the sensor in ping mode. - * In this mode the sensor only scans the surrounding upon request, ie by calling fetchSample method. - * The sensor reports the distance, expressed in meters, to the eight nearest objects in sight. The theoretical range of the sensor is 0,04 to 2.54 meter. - * If there are less then eight objects within the sensors range the sensor will reports Float.POSITIVE_INFINITY. - * Fetching a sample in ping mode takes about 70 ms. - * @return the sample provider - */ - public SampleProvider getPingMode() { - return getMode(1); - } - - public void enable() { - setMode(MODE_CONTINUOUS); - } - - public void disable() { - setMode(MODE_OFF); - } - - public boolean isEnabled() { - return (currentMode==MODE_OFF) ? false : true; - } - - /** Sets the sensor to CONTINUOUS, PING or OFF - * @param mode - * @return - * True, if the mode was changed.
    - * False, if the mode was already in the requested state. - */ - protected boolean setMode(byte mode) { - if (mode !=currentMode) { - byteBuff[0]=mode; - sendData(REG_MODE, byteBuff, 1); - currentMode=mode; - return true; - } - return false; - } - - - public class DistanceMode implements SensorMode { - - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - if (setMode(MODE_CONTINUOUS)) { - dataAvailableTime = System.currentTimeMillis()+DELAY_DATA_CONTINUOUS; // when the sensor was in another mode, the wait period just start. Otherwise it was set the last time this method was called; - } - waitUntil(dataAvailableTime); - getData(REG_DISTANCE, byteBuff, 1); - int raw=byteBuff[0] & 0xff; - - sample[offset]= (raw==255) ? Float.POSITIVE_INFINITY : raw*TOSI; - - dataAvailableTime = System.currentTimeMillis()+DELAY_DATA_CONTINUOUS; - } - - @Override - public String getName() { - return "Distance"; - } - - } - - public class PingMode implements SensorMode { - - @Override - public int sampleSize() { - return 8; - } - - @Override - public void fetchSample(float[] sample, int offset) { - setMode(MODE_PING); - Delay.msDelay(DELAY_DATA_PING); - getData(REG_DISTANCE, byteBuff, 8); - for (int i = 0; i < 8;i++) { - int raw=byteBuff[i] & 0xff; - sample[i+offset]= (raw==255) ? Float.POSITIVE_INFINITY : raw*TOSI; - } - currentMode=MODE_OFF; - } - - @Override - public String getName() { - return "Distances"; - } - } - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/RCXLightSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/RCXLightSensor.java deleted file mode 100644 index 62ad1fb..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/RCXLightSensor.java +++ /dev/null @@ -1,146 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.robotics.*; - -/** - * LEGO RCX light Sensor
    - * The RCX light sensor measures light levels of reflected or ambient light. - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    RedMeasures the light value when illuminated with a red light source.N/A, normalized {@link #getRedMode() }
    AmbientMeasures the light value of ambient light.N/A, normalized {@link #getAmbientMode() }
    - * - *

    - * - */ -public class RCXLightSensor extends AnalogSensor implements SensorConstants, - LampController { - private static final int SWITCH_DELAY = 10; - private boolean floodlight = false; - - /** - * Create an RCX light sensor object attached to the specified port. The - * sensor will be activated, i.e. the LED will be turned on. - * - * @param port - * port, e.g. Port.S1 - */ - public RCXLightSensor(Port port) { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[] { new RedMode(), new AmbientMode() }); - port.setTypeAndMode(TYPE_REFLECTION, MODE_RAW); - setFloodlight(true); - } - - public int getFloodlight() { - if (this.floodlight == true) - return Color.RED; - else - return Color.NONE; - } - - public boolean isFloodlightOn() { - return floodlight; - } - - public void setFloodlight(boolean floodlight) { - this.floodlight = floodlight; - if (floodlight == true) - switchType(TYPE_REFLECTION, SWITCH_DELAY); - else - switchType(TYPE_CUSTOM, SWITCH_DELAY); - } - - public boolean setFloodlight(int color) { - if (color == Color.RED) { - setFloodlight(true); - return true; - } else if (color == Color.NONE) { - setFloodlight(false); - return true; - } else - return false; - } - - /** - * get a sample provider the returns the light value when illuminated with a - * Red light source. - * - * @return the sample provider - */ - public SensorMode getRedMode() { - return getMode(0); - } - - /** - * get a sample provider the returns the light value when illuminated without - * a light source. - * - * @return the sample provider - */ - public SensorMode getAmbientMode() { - return getMode(1); - } - - private class RedMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - setFloodlight(true); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() { - return "Red"; - } - } - - private class AmbientMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - setFloodlight(false); - sample[offset] = 1.0f - normalize(port.getPin1()); - } - - @Override - public String getName() { - return "Ambient"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/RCXRotationSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/RCXRotationSensor.java deleted file mode 100644 index 79cd38c..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/RCXRotationSensor.java +++ /dev/null @@ -1,160 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.Port; -import lejos.robotics.Tachometer; -import lejos.utility.Delay; - -/** - * Provide access to the Lego RCX Rotation Sensor. - * - * The sensor records the direction and degree of rotation. A full rotation - * will result in a count of +/-16. Thus each count is 22.5 degrees. - * - * @author Andy Shaw - * - */ -public class RCXRotationSensor extends AnalogSensor implements Tachometer, SensorConstants -{ - /** - * The incremental count for one whole rotation (360 degrees). - */ - public static final int ONE_ROTATION = 16; - protected static final int UPDATE_TIME = 2; - protected int count; - protected final Reader reader; - private int speed = 0; - private long previous_time = System.currentTimeMillis(); - - /** - * Create an RCX rotation sensor object attached to the specified port. - * @param p port, e.g. Port.S1 - */ - public RCXRotationSensor(Port p) - { - super(p); - port.setTypeAndMode(TYPE_ANGLE, MODE_RAW); - reader = new Reader(); - reader.setDaemon(true); - reader.setPriority(Thread.MAX_PRIORITY); - reader.start(); - count = 0; - } - - - /** - * Returns the current phase of the sensor. - * - * The sensor returns four distinct values read by the ADC port. Each value - * represents a phase in the rotation. The sequence of the phases is: - * 0 1 3 2 and 0 2 3 1 - * The transition from one phase to another can be used to identify the - * direction of rotation. - * @return the current rotation phase. - */ - protected int getPhase() - { - int val = NXTRawIntValue(port.getPin1()); - if (val < 450) return 0; - if (val < 675) return 1; - if (val < 911) return 2; - return 3; - } - - /** - * The following table when indexed by [previous phase][current phase] - * provides the current direction of rotation. Invalid phase combinations - * result in zero. - */ - protected static final int [][]inc = {{0, 1, -1, 0}, - {-1, 0, 0, 1}, - {1, 0, 0, -1}, - {0, -1, 1, 0}}; - - - protected class Reader extends Thread - { - /** - * Sensor reader thread. - * Reads the current phase of the sensor and computes the new count. - * NOTE: There is a problem with this sensor when a read spans the - * point at which the sensor output changes from one value to another. - * The result of this can be a "ghost value". For instance if the read - * occurs when moving from state 2 to state 0 then a false reading of - * state 1 may be read. To reduce this problem a new state is not - * accepted until two consecutive reads return the same state. - */ - public void run() - { - int prev = getPhase(); - int cur1 = prev; - while (true) - { - int cur2 = getPhase(); - if (cur1 == cur2) - { - if (cur2 != prev) - { - synchronized(this) - { - count += inc[prev][cur2]; - - // TODO: This should probably indicate sign for speed if Motor does too. Also, Javadocs - // for interface should also specify whether sign applies for speed. - // TODO: This will never report 0 speed! Need some algorithm to realize when it is at 0 speed, - // especially when it goes from fast to dead stop. - // Estimate speed by calculating time elapsed for every increment - int time_elapsed = (int)(System.currentTimeMillis() - previous_time); - speed = (360 * 1000) / (time_elapsed * ONE_ROTATION); - previous_time = System.currentTimeMillis(); - } - prev = cur2; - - } - } - cur1 = cur2; - - Delay.msDelay(UPDATE_TIME); - } - } - } - - /** - * Returns the tachometer count. - * NOTE: Because the RCX rotation sensor only counts 16 increments for a full rotation, the degree values - * are only accurate to +- 22.5 degrees. - * @return tachometer count in degrees, in increments of 22.5 degrees (rounded off) - */ - public int getTachoCount() - { - return (360 * count) / ONE_ROTATION; - } - - /** - * Returns the raw values from the rotation sensor instead of degrees. - * A full rotation of 360 degrees results in count increasing by 16. - * @return the raw tachometer reading - */ - public int getRawTachoCount() { - return count; - } - - /** - * Reset the tacho count to zero. - */ - public void resetTachoCount() - { - synchronized(reader) - { - count = 0; - } - } - - // TODO: Change to getTachoSpeed - public int getRotationSpeed() { - // TODO: Ok, if it has been longer than last delay between pulses, then it should start to - // calculate speed based on the time between pulses here in this method. In other words, the - // speed value starts working its way towards zero. Might not actually get to 0, but could - // choose some arbitrary value to round to zero. - return speed; - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/RCXThermometer.java b/ev3classes/src/main/java/lejos/hardware/sensor/RCXThermometer.java deleted file mode 100644 index ca53a50..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/RCXThermometer.java +++ /dev/null @@ -1,87 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.LegacySensorPort; - - -/** - * Lego RCX temperature sensor
    - * The sensor measures both atmospheric pressure and temperature. - * - *

    - * The code for this sensor has not been tested. Please report test results to - * the leJOS forum. - *

    - * - *

    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    Supported modes
    Mode nameDescriptionunit(s)Getter
    TemperatureMeasures temperatureDegree Celcius {@link #getTemperatureMode() }
    - * - * - * See The - * leJOS sensor framework - * See {@link lejos.robotics.SampleProvider leJOS conventions for - * SampleProviders} - * - *

    - * - * - * @author Soren Hilmer - * - */ -public class RCXThermometer extends AnalogSensor implements SensorConstants { - LegacySensorPort port; - - /** - * Create an RCX temperature sensor object attached to the specified port. - * @param port port, e.g. Port.S1 - */ - public RCXThermometer(LegacySensorPort port) - { - super(port); - init(); - } - - protected void init() { - setModes(new SensorMode[]{ new TemperatureMode() }); - port.setTypeAndMode(TYPE_TEMPERATURE, MODE_RAW); - } - - /** - * Return a sample provider in temperature mode - */ - public SensorMode getTemperatureMode() { - return getMode(0); - } - - private class TemperatureMode implements SensorMode { - @Override - public int sampleSize() { - return 1; - } - - @Override - public void fetchSample(float[] sample, int offset) { - sample[offset] = (785-NXTRawValue(port.getPin1()))/8.0f +273.15f; // Kelvin - } - - @Override - public String getName() { - return "Temperature"; - } - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/RFIDSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/RFIDSensor.java deleted file mode 100644 index a291738..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/RFIDSensor.java +++ /dev/null @@ -1,268 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; -import lejos.utility.Delay; - -/** - * Support for the Codatex RFID Sensor. - * This device requires delays between various commands for them to - * function correctly, it also enters a sleep mode and requires to be woken up. - * The methods in this class fall into two categories. - * Basic commands - * These pretty much match one to one with the device command set. They do not - * incorporate any delays, or wake up code. They can be used by user programs - * but if they are then appropriate delays etc. must be used. They are provided - * to allow more sophisticated user programs access to the low level device. - * - * High level commands - * These provide higher level access to the device and are often implemented via - * several i2c commands. They do include delays and wake up logic. - * - * @author andy - */ -public class RFIDSensor extends I2CSensor -{ - /* - * Notes - * This sensor is a little tricky to deal with. It will enter a sleep mode - * if not used for a while and so will need to be woken up. Plus it seems - * very sensitive to timing of requests (hence the use of various delays). - */ - // Command Registers and bytes - private static final int REG_CMD = 0x41; - private static final byte CMD_STOP = 0; - private static final byte CMD_SINGLEREAD = 1; - private static final byte CMD_CONTINUOUSREAD = 2; - private static final byte CMD_BOOTLOADER = (byte)0x81; - private static final byte CMD_STARTFIRMWARE = (byte)0x83; - - // Data registers - private static final int REG_STATUS = 0x32; - private static final int REG_DATA = 0x42; - private static final int LEN_DATA = 5; - private static final int REG_SERIALNO = 0xA0; - private static final int LEN_SERIALNO = 16; - - private static final int DEFAULT_ADDRESS = 4; - - // Various delays - private static final int DELAY_WAKEUP = 5; - private static final int DELAY_FIRMWARE = 100; - private static final int DELAY_ACQUIRE = 250; - private static final int DELAY_READ = 200; - - private byte buf1[] = new byte[1]; - private long nextRead = now(); - - private void init() - { - // We seem to need to give the device a bit of a kick to get it going - // doing a read seems to do the job... - wakeUp(); - readTransponder(false); - } - /** - * Create a class to provide access to the device. Perform device - * initialization. - * @param port The sensor port to use for this device. - */ - public RFIDSensor(I2CPort port) - { - super(port, DEFAULT_ADDRESS); - init(); - } - - /** - * Create a class to provide access to the device. Perform device - * initialization. - * @param port The sensor port to use for this device. - */ - public RFIDSensor(Port port) - { - super(port, DEFAULT_ADDRESS, TYPE_LOWSPEED_9V); - init(); - } - - /** - * Helper function, return current time, used as basis of required inter - * command delays. - * @return - */ - private long now() - { - return System.currentTimeMillis(); - } - - /** - * Helper function wait until a specific time has arrived - */ - private void waitUntil(long target) - { - long d = target - now(); - if (d > 0) - Delay.msDelay(d); - } - - - /** - * The sensor will go into a power save mode after a short time. This means - * that we will need to wake it up before issuing commands. Includes - * the required Delay.msDelay. - */ - public void wakeUp() - { - // Simply send a dummy command to the device - sendData(0, (byte)0); - Delay.msDelay(DELAY_WAKEUP); - } - - - /** - * We over-ride the default implementation to ensure that the device is - * awake before we talk to it. - * @param register The register to read the string from. - * @param len - * @return The requested string. - */ - protected String fetchString(byte register, int len) - { - wakeUp(); - return super.fetchString(register, len); - } - - /** - * Start the firmware on the RFID device. - * NOTES: It seems that you need to issue this command (or some other - * firmware command), prior to attempting to read the version number etc. - * Does not wake up the device or contain any delays. - */ - public void startFirmware() - { - sendData(REG_CMD, CMD_STARTFIRMWARE); - } - - /** - * Enter boot loader mode. - * Does not wake up the device or include any delays. - * - */ - public void startBootLoader() - { - sendData(REG_CMD, CMD_BOOTLOADER); - } - - /** - * Obtain the serial number of the RFID Sensor. - * NOTES: To obtain the serial number the device must be in boot loader - * mode. This function will switch into this mode and then return to - * normal mode on completion. - * @return the 12 byte serial number if ok or null if there is an error - */ - public byte [] getSerialNo() - { - wakeUp(); - // must be in boot loader mode - startBootLoader(); - Delay.msDelay(DELAY_FIRMWARE); - byte [] ret = new byte[LEN_SERIALNO]; - getData(REG_SERIALNO, ret, ret.length); - startFirmware(); - return ret; - } - - /** - * Read the status from the device. - * Does not wake up the device or include any delays. - * @return 1 data available 0 no data < 0 error - */ - public int getStatus() - { - getData(REG_STATUS, buf1, buf1.length); - return (int)buf1[0]; - } - - /** - * Start a single read from the device. - * Does not wake up the device or include any delays. - */ - public void startSingleRead() - { - sendData(REG_CMD, CMD_SINGLEREAD); - } - - /** - * Start continually reading from the device. - * Does not wake up the device or include any delays. - */ - public void startContinuousRead() - { - sendData(REG_CMD, CMD_CONTINUOUSREAD); - } - - /** - * Send a stop command to the device. - * Places the device into sleep mode. - */ - public void stop() - { - sendData(REG_CMD, CMD_STOP); - } - - /** - * Read a transponder id. - * Reads the transponder using either continuous or single shot mode. If - * using single shot mode the tag must me available now. If using continuous - * mode then after the first call, the tag can be presented at any time - * and a subsequent read will return the results. - * @param continuous Should we use continuous mode - * @return null if error or no data available, otherwise an array of five id bytes - */ - public byte [] readTransponder(boolean continuous) - { - // Wait until a new read is valid - waitUntil(nextRead); - wakeUp(); - if (continuous) - { - // If not ready, start a new command - if (getStatus() <= 0) - { - startContinuousRead(); - Delay.msDelay(DELAY_ACQUIRE); - } - } - else - { - startSingleRead(); - Delay.msDelay(DELAY_ACQUIRE); - } - // make a note of when it is safe to do another read. - nextRead = now() + DELAY_READ; - // Get the data - boolean valid = false; - byte [] ret = new byte[LEN_DATA]; - for(int i = 0; i < ret.length; i++) - { - getData(REG_DATA+i, buf1, buf1.length); - ret[i] = buf1[0]; - if (buf1[0] != 0) - valid = true; - } - return (valid ? ret : null); - } - - public long readTransponderAsLong(boolean continuous) - { - byte [] id = readTransponder(continuous); - if (id == null) return 0; - long ret = 0; - for(int i = id.length - 1; i >= 0; i--) - { - ret <<= 8; - ret |= ((long)id[i] & 0xff); - } - return ret; - } -} - diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/SensorConstants.java b/ev3classes/src/main/java/lejos/hardware/sensor/SensorConstants.java deleted file mode 100644 index de49e3d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/SensorConstants.java +++ /dev/null @@ -1,61 +0,0 @@ -package lejos.hardware.sensor; - -/** - * Constants used to set Sensor types and modes. - * - */ -public interface SensorConstants { - - /** - * Colors used as the output value when in full mode. Values are - * compatible with LEGO firmware. Note that these color values - * are normally converted to use the standard leJOS colors - * as defined in the Color class. - */ - - public static final int BLACK = 1; - public static final int BLUE = 2; - public static final int GREEN = 3; - public static final int YELLOW = 4; - public static final int RED = 5; - public static final int WHITE = 6; - public static final int BROWN = 7; - /** Color sensor data RED value index. */ - public static final int RED_INDEX = 0; - /** Color sensor data GREEN value index. */ - public static final int GREEN_INDEX = 1; - /** Color sensor data BLUE value index. */ - public static final int BLUE_INDEX = 2; - /** Color sensor data BLANK/Background value index. */ - public static final int BLANK_INDEX = 3; - - public static final int TYPE_NO_SENSOR = 0; - public static final int TYPE_SWITCH = 1; - public static final int TYPE_TEMPERATURE = 2; - public static final int TYPE_REFLECTION = 3; - public static final int TYPE_ANGLE = 4; - public static final int TYPE_LIGHT_ACTIVE = 5; - public static final int TYPE_LIGHT_INACTIVE = 6; - public static final int TYPE_SOUND_DB = 7; - public static final int TYPE_SOUND_DBA = 8; - public static final int TYPE_CUSTOM = 9; - public static final int TYPE_LOWSPEED = 10; - public static final int TYPE_LOWSPEED_9V = 11; - public static final int TYPE_HISPEED = 12; - public static final int TYPE_COLORFULL = 13; - public static final int TYPE_COLORRED = 14; - public static final int TYPE_COLORGREEN = 15; - public static final int TYPE_COLORBLUE = 16; - public static final int TYPE_COLORNONE = 17; - // additional leJOS types for the EV3 - public static final int TYPE_HIGHSPEED = 18; - public static final int TYPE_HIGHSPEED_9V = 19; - - public static final int MIN_TYPE = 0; - public static final int MAX_TYPE = 19; - - // Only RAW mode on the EV3 - public static final int MODE_RAW = 0x00; - /** MAX value returned as a RAW sensor reading for standard NXT A/D sensors */ - public static final int NXT_ADC_RES = 1023; -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/SensorMode.java b/ev3classes/src/main/java/lejos/hardware/sensor/SensorMode.java deleted file mode 100644 index b1bdb1f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/SensorMode.java +++ /dev/null @@ -1,15 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.robotics.SampleProvider; - -public interface SensorMode extends SampleProvider -{ - /** - * return a string description of this sensor mode - * @return The description/name of this mode - */ - public String getName(); - - // TODO: Return additional mode information - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/SensorModes.java b/ev3classes/src/main/java/lejos/hardware/sensor/SensorModes.java deleted file mode 100644 index f94cf77..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/SensorModes.java +++ /dev/null @@ -1,56 +0,0 @@ -package lejos.hardware.sensor; - -import java.util.ArrayList; - -/** - * Provide access to the modes supported by a sensor - * @author andy - * - */ -public interface SensorModes extends SensorMode -{ - /** - * Return a list of string descriptions for the sensors available modes. - * @return list of string descriptions - */ - public ArrayList getAvailableModes(); - - /** - * Return the sample provider interface for the requested mode - * @param mode the mode number - * @return the sample provider for this mode - */ - public SensorMode getMode(int mode); - - /** - * Return the sample provider for the request mode - * @param modeName the name/description of the mode - * @return the sample provider for the requested mode. - */ - public SensorMode getMode(String modeName); - - /** - * Sets the current mode for fetching samples - * @param mode the index number of the mode. Index number corresponds with the item order of the list from getAvailableModes(). - */ - public void setCurrentMode(int mode); - - /** - * Sets the current mode for fetching samples - * @param modeName the name of the mode. name corresponds with the item value of the list from getAvailableModes(). - */ - public void setCurrentMode(String modeName); - - /** Gets the index number of the current mode. - * @return the index number of the mode. Index number corresponds with the item order of the list from getAvailableModes(). - */ - public int getCurrentMode(); - - /** Gets the number of supported modes - * @return the number of supported modes - */ - public int getModeCount(); - - - -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/SumoEyesSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/SumoEyesSensor.java deleted file mode 100644 index c4f5f66..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/SumoEyesSensor.java +++ /dev/null @@ -1,101 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.Port; - -/** - * Java class for MINDSENSORS NXT SumoEyes (triple zone IR obstacle detector). - * - * @author Daniele Benedettelli - * @version 1.0 - */ -public class SumoEyesSensor extends AnalogSensor implements SensorConstants { - - protected final static long SWITCH_DELAY = 10; - - /** The Constant NO_DETECTION (0). */ - public final static int NO_DETECTION = 0; - - /** The Constant LEFT (1). */ - public final static int LEFT = 1; - - /** The Constant CENTER (2). */ - public final static int CENTER = 2; - - /** The Constant RIGHT (3). */ - public final static int RIGHT = 3; - - /** The long range. */ - private boolean longRange = false; - - /** - * Default constructor. - * - * @param port the sensor port - */ - public SumoEyesSensor(AnalogPort port) { - super(port); - port.setTypeAndMode(TYPE_LIGHT_INACTIVE,MODE_RAW); - } - - - /** - * Default constructor. - * - * @param port the sensor port - */ - public SumoEyesSensor(Port port) { - super(port); - this.port.setTypeAndMode(TYPE_LIGHT_INACTIVE,MODE_RAW); - } - - /** - * Gets the raw value of the sensor. - * - * @return the raw sensor value - */ - public int getValue() { - return NXTRawIntValue(port.getPin1()); - } - - /** - * Returns the detected zone (NO_DETECTION (0) , RIGHT (1), CENTER (2), LEFT (3)) - * @return detected zone constant - * - */ - public int getObstacle() { - int value = NXTRawIntValue(port.getPin1()); - if (value == 1023) { - return NO_DETECTION; - } - if (value > 300 && value < 400) { - return CENTER; - } - if (value > 600) { - return LEFT; - } - return RIGHT; - } - - /** - * Enables long range of the sensor. - * - * @param longRange if true, enables long range, if false enables short range - */ - public void setLongRange(boolean longRange) { - this.longRange = longRange; - if (this.longRange) { - switchType(TYPE_LIGHT_ACTIVE, SWITCH_DELAY); - } else - switchType(TYPE_LIGHT_INACTIVE, SWITCH_DELAY); - } - - /** - * Returns the current range of the sensor. - * - * @return current range of the sensor - */ - public boolean isLongRange() { - return longRange; - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/UARTSensor.java b/ev3classes/src/main/java/lejos/hardware/sensor/UARTSensor.java deleted file mode 100644 index a8f6b76..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/UARTSensor.java +++ /dev/null @@ -1,92 +0,0 @@ -package lejos.hardware.sensor; - -import lejos.hardware.DeviceException; -import lejos.hardware.port.Port; -import lejos.hardware.port.UARTPort; - -/** - * Base class for EV3 UART based sensors. UART sensor drivers should extend this class - * @author andy - * - */ -public class UARTSensor extends BaseSensor -{ - protected UARTPort port; - protected int currentMode; - - - /** - * Standard constructor for a UARTSensor initialises things and places the - * device into mode 0. - * @param port The port the sensor is attached to. - */ - public UARTSensor(UARTPort port) - { - this(port, 0); - } - - /** - * Standard constructor for a UARTSensor initialises things and places the - * device into mode 0. - * @param port The port the sensor is attached to. - */ - public UARTSensor(Port port) - { - this(port, 0); - } - - /** - * Create the sensor object and switch to the selected mode - * @param port The port the sensor is attached to. - * @param mode Operating mode for the sensor. - */ - public UARTSensor(UARTPort port, int mode) - { - this.port = port; - if (!port.setMode(mode)) - throw new DeviceException("Unable to initialize device"); - currentMode = mode; - } - - /** - * Create the sensor object and switch to the selected mode - * @param port The port the sensor is attached to. - * @param mode Operating mode for the sensor. - */ - public UARTSensor(Port port, int mode) - { - this.port = port.open(UARTPort.class); - if (!this.port.setMode(mode)) - { - this.port.close(); - throw new IllegalArgumentException("Invalid sensor mode"); - } - currentMode = mode; - releaseOnClose(this.port); - } - - - /** - * Switch to the selected mode (if not already in that mode) and delay for the - * specified period to allow the sensor to settle in the new mode.
    - * A mode of -1 resets the sensor. - * TODO: There really should be a better way to work out when the switch is - * complete, if you don't wait though you end up reading data from the previous - * mode. - * @param newMode The mode to switch to. - * @param switchDelay Time in mS to delay after the switch. - */ - protected void switchMode(int newMode, long switchDelay) - { - if (currentMode != newMode) - { - if (newMode == -1) - port.resetSensor(); - else if (!port.setMode(newMode)) - throw new IllegalArgumentException("Invalid sensor mode"); - currentMode = newMode; - //Delay.msDelay(switchDelay); - } - - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/sensor/package-info.java b/ev3classes/src/main/java/lejos/hardware/sensor/package-info.java deleted file mode 100644 index 40effde..0000000 --- a/ev3classes/src/main/java/lejos/hardware/sensor/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Access to all the sensors that are supported on the EV3. - * - * Devices that are not strictly sensors are in lejos.hardwae.devie. - * - */ -package lejos.hardware.sensor; diff --git a/ev3classes/src/main/java/lejos/hardware/video/Video.java b/ev3classes/src/main/java/lejos/hardware/video/Video.java deleted file mode 100644 index 3e5887d..0000000 --- a/ev3classes/src/main/java/lejos/hardware/video/Video.java +++ /dev/null @@ -1,67 +0,0 @@ -package lejos.hardware.video; - -public interface Video { - // We only provide the most common formats and definitions - public static final int PIX_FMT_MJPEG = VideoUtils.fourcc('M', 'J', 'P', 'G'); /* Motion-JPEG */ - public static final int PIX_FMT_JPEG = VideoUtils.fourcc('J', 'P', 'E', 'G'); /* JFIF JPEG */ - public static final int PIX_FMT_YUYV = VideoUtils.fourcc('Y', 'U', 'Y', 'V'); /* 16 YUV 4:2:2 */ - - public static final int FIELD_ANY = 0; - public static final int FIELD_NONE = 1; - public static final int FIELD_INTERLACED = 4; - /** - * Open the device and make it available for use, specify the desired frame size. Note that the actual - * frame size may be adjusted to conform to the capabilities of the device. - * @param w the desired frame width - * @param h the desired frame height - * @param format desired pixel format - * @param field desired field layout - * @param fps the desired frame rate - * @throws java.io.IOException - */ - public void open(int w, int h, int format, int field, int fps) throws java.io.IOException; - - /** - * Open the device and make it available for use, specify the desired frame size. Note that the actual - * frame size may be adjusted to conform to the capabilities of the device. - * @param w the desired frame width - * @param h the desired frame height - * @throws java.io.IOException - */ - public void open(int w, int h) throws java.io.IOException; - - /** - * Grab a single frame from the device and store the image into the supplied array - * @param frame array to store the frame - * @return the size of the frame grabbed (in bytes) - * @throws java.io.IOException - */ - public int grabFrame(byte[] frame) throws java.io.IOException; - - /** - * Close the webcam, the device will not be available after this call - * @throws java.io.IOException - */ - public void close() throws java.io.IOException; - - - - /** - * Create a byte array suitable for holding a single video frame - * @return the frame array - */ - public byte[] createFrame(); - - /** - * Return the frame width - * @return width in pixels - */ - public int getWidth(); - - /** - * return the frame height - * @return height in pixels - */ - public int getHeight(); - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/video/VideoUtils.java b/ev3classes/src/main/java/lejos/hardware/video/VideoUtils.java deleted file mode 100644 index b80be7f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/video/VideoUtils.java +++ /dev/null @@ -1,9 +0,0 @@ -package lejos.hardware.video; - -public class VideoUtils -{ - public static int fourcc(char a, char b, char c, char d) - { - return ((int)a & 0xff) | (((int)b & 0xff) << 8) | (((int)c & 0xff) << 16) | (((int)d & 0xff) << 24); - } -} diff --git a/ev3classes/src/main/java/lejos/hardware/video/YUYVImage.java b/ev3classes/src/main/java/lejos/hardware/video/YUYVImage.java deleted file mode 100644 index 85c334f..0000000 --- a/ev3classes/src/main/java/lejos/hardware/video/YUYVImage.java +++ /dev/null @@ -1,120 +0,0 @@ -package lejos.hardware.video; - - - -import lejos.hardware.lcd.GraphicsLCD; - - - /** - * Class to represent a YUV video image - * @author Gabriel Ferrer, Andy - * - */ - public class YUYVImage { - private byte[] pix; - private int width, height; - - /** - * Create a YUYV image of the requested size using the byte array as the source of pixel information - * @param pix pixels - * @param width image width - * @param height image height - */ - public YUYVImage(byte[] pix, int width, int height) { - this.pix = pix; - this.width = width; - this.height = height; - } - - /** - * Create a new YUYV image of the specified size - * @param width - * @param height - */ - public YUYVImage(int width, int height) { - this.pix = new byte[width*height*2]; - this.width = width; - this.height = height; - } - - - /** - * return the number of pixels in the image - * @return number of pixels - */ - public int getNumPixels() {return pix.length / 2;} - - /** - * return the image width - * @return width - */ - public int getWidth() {return width;} - - - /** - * return the image height - * @return height - */ - public int getHeight() {return height;} - - - /** - * return the Y component of the specified pixel - * @param x - * @param y - * @return Y component - */ - public int getY(int x, int y) { - return pix[2 * (y * width + x)]; - } - - /** - * return the U component of the specified pixel - * @param x - * @param y - * @return U component - */ - public int getU(int x, int y) { - return pix[getPairBase(x, y) + 1]; - } - - /** - * return the V component of the specified pixel - * @param x - * @param y - * @return V component - */ - public int getV(int x, int y) { - return pix[getPairBase(x, y) + 3]; - } - - private int getPairBase(int x, int y) { - return 2 * (y * width + (x - x % 2)); - } - - /** - * Return the mean of the Y components for the image (mean brightness) - * @return mean Y value - */ - public int getMeanY() { - int total = 0; - for (int i = 0; i < pix.length; i += 2) { - total += (int)pix[i] & 0xff; - } - return total / getNumPixels(); - } - - /** - * Display the image at the specified location on the provided monochrome device or image. Pixels - * with a Y value below threshold will be set, those above unset. - * @param threshold - */ - public void display(GraphicsLCD device, int xDest, int yDest, int threshold) { - for (int i = 0; i < pix.length; i += 2) { - int x = (i / 2) % width; - int y = (i / 2) / width; - device.setPixel(xDest+x, yDest+y, ((int)pix[i] & 0xff) < threshold ? 1 : 0); - } - } - } - \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/hardware/video/package-info.java b/ev3classes/src/main/java/lejos/hardware/video/package-info.java deleted file mode 100644 index f03a5e2..0000000 --- a/ev3classes/src/main/java/lejos/hardware/video/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Access to video devices - */ -package lejos.hardware.video; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/dbus/Adapter.java b/ev3classes/src/main/java/lejos/internal/dbus/Adapter.java deleted file mode 100644 index be8f2ba..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/Adapter.java +++ /dev/null @@ -1,105 +0,0 @@ -package lejos.internal.dbus; -import lejos.internal.dbus.DBusProperties.DBusProperty; -import lejos.internal.dbus.DBusProperties.DBusPropertyAccessType; - -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.DBusInterfaceName; -import org.freedesktop.dbus.Path; -import org.freedesktop.dbus.UInt32; - -@DBusInterfaceName("org.bluez.Adapter") -public interface Adapter extends DBusInterface, DBusProperties.PropertiesAccess{ - public static enum Properties implements DBusProperties.PropertyEnum { - - /** - * The Bluetooth device address. Example: "00:11:22:33:44:55" - */ - @DBusProperty(type = String.class, access = DBusPropertyAccessType.READONLY) - Address, - - /** - * The Bluetooth friendly name. This value can be changed and a PropertyChanged - * signal will be emitted. - */ - @DBusProperty(type = String.class) - Name, - - /** - * The Bluetooth class of device. - * - * @since BlueZ 4.34 - */ - @DBusProperty(type = UInt32.class, access = DBusPropertyAccessType.READONLY) - Class, - - /** - * Switch an adapter on or off. This will also set the appropriate connectable - * state. - */ - @DBusProperty(type = boolean.class) - Powered, - - /** - * Switch an adapter to discoverable or non-discoverable to either make it visible - * or hide it. This is a global setting and should only be used by the settings - * application. - * - * If the DiscoverableTimeout is set to a non-zero value then the system will set - * this value back to false after the timer expired. - * - * In case the adapter is switched off, setting this value will fail. - * - * When changing the Powered property the new state of this property will be - * updated via a PropertyChanged signal. - */ - @DBusProperty(type = boolean.class) - Discoverable, - - /** - * Switch an adapter to pairable or non-pairable. This is a global setting and - * should only be used by the settings application. - * - * Note that this property only affects incoming pairing requests. - */ - @DBusProperty(type = boolean.class) - Pairable, - - /** - * The pairable timeout in seconds. A value of zero means that the timeout is - * disabled and it will stay in pairable mode forever. - */ - @DBusProperty(type = UInt32.class) - PaireableTimeout, - - /** - * The discoverable timeout in seconds. A value of zero means that the timeout is - * disabled and it will stay in discoverable/limited mode forever. - * - * The default value for the discoverable timeout should be 180 seconds (3 - * minutes). - */ - @DBusProperty(type = UInt32.class) - DiscoverableTimeout, - - /** - * Indicates that a device discovery procedure is active. - */ - @DBusProperty(type = boolean.class, access = DBusPropertyAccessType.READONLY) - Discovering, - - /** - * List of device object paths. - */ - @DBusProperty(type = Path[].class, access = DBusPropertyAccessType.READONLY) - Devices - } - - Path CreatePairedDevice(String address, Path agent, String capability); - - /** - * Returns list of device object paths. - */ - Path[] ListDevices(); - Path FindDevice(String address); - void RemoveDevice(Path device); -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/dbus/Agent.java b/ev3classes/src/main/java/lejos/internal/dbus/Agent.java deleted file mode 100644 index 9e70c52..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/Agent.java +++ /dev/null @@ -1,76 +0,0 @@ -package lejos.internal.dbus; - -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.DBusInterfaceName; -import org.freedesktop.dbus.Path; -import org.freedesktop.dbus.UInt32; - -@DBusInterfaceName("org.bluez.Agent") -public interface Agent extends DBusInterface { - /** - * This method gets called when the service daemon unregisters the agent. An - * agent can use it to do cleanup tasks. There is no need to unregister the - * agent, because when this method gets called it has already been - * unregistered. - */ - void Release(); - - /** - * This method gets called when the service daemon needs to get the passkey - * for an authentication. - * - * The return value should be a string of 1-16 characters length. The string - * can be alphanumeric. - */ - String RequestPinCode(Path device); - - /** - * This method gets called when the service daemon needs to get the passkey - * for an authentication. - * - * The return value should be a numeric value between 0-999999. - */ - UInt32 RequestPasskey(Path device); - - /** - * This method gets called when the service daemon needs to display a - * passkey for an authentication. - * - * The entered parameter indicates the number of already typed keys on the - * remote side. - * - * An empty reply should be returned. When the passkey needs no longer to be - * displayed, the Cancel method of the agent will be called. - * - * During the pairing process this method might be called multiple times to - * update the entered value. - */ - void DisplayPasskey(Path device, UInt32 passkey, byte entered); - - /** - * This method gets called when the service daemon needs to confirm a - * passkey for an authentication. - * - * To confirm the value it should return an empty reply or an error in case - * the passkey is invalid. - */ - void RequestConfirmation(Path device, UInt32 passkey); - - /** - * This method gets called when the service daemon needs to authorize a - * connection/service request. - */ - void Authorize(Path device, String uuid); - - /** - * This method gets called if a mode change is requested that needs to be - * confirmed by the user. An example would be leaving flight mode. - */ - void ConfirmModeChange(String mode); - - /** - * This method gets called to indicate that the agent request failed before - * a reply was returned. - */ - void Cancel(); -} diff --git a/ev3classes/src/main/java/lejos/internal/dbus/DBusBluez.java b/ev3classes/src/main/java/lejos/internal/dbus/DBusBluez.java deleted file mode 100644 index e0ce0c2..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/DBusBluez.java +++ /dev/null @@ -1,190 +0,0 @@ -package lejos.internal.dbus; - -import org.freedesktop.dbus.DBusConnection; -import org.freedesktop.dbus.Path; -import org.freedesktop.dbus.Variant; -import org.freedesktop.dbus.exceptions.DBusException; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -public class DBusBluez { - private Manager dbusManager; - private DBusConnection dbusConn; - private Path adapterPath; - private Adapter adapter; - - public DBusBluez() throws DBusException { - dbusConn = DBusConnection.getConnection(DBusConnection.SYSTEM); - dbusManager = dbusConn.getRemoteObject("org.bluez", "/", Manager.class); - selectAdapter(dbusManager.DefaultAdapter()); - } - - public void selectAdapter(Path adapterPath) throws DBusException { - adapter = dbusConn.getRemoteObject("org.bluez", adapterPath.getPath(), Adapter.class); - this.adapterPath = adapterPath; - } - /* - * (non-Javadoc) - * - * @see org.bluez.BlueZAPI#getAdapterAddress() - */ - public String getAdapterAddress() { - return DBusProperties.getStringValue(adapter, Adapter.Properties.Address); - } - - /* - * (non-Javadoc) - * - * @see org.bluez.BlueZAPI#getAdapterDeviceClass() - */ - public int getAdapterDeviceClass() { - // Since BlueZ 4.34 - Integer deviceClass = DBusProperties.getIntValue(adapter, Adapter.Properties.Class); - if (deviceClass == null) { - return 0; // What should we return? - } else { - return deviceClass.intValue(); - } - } - - /* - * (non-Javadoc) - * - * @see org.bluez.BlueZAPI#getAdapterName() - */ - public String getAdapterName() { - return DBusProperties.getStringValue(adapter, Adapter.Properties.Name); - } - - - public boolean authenticateRemoteDevice(String deviceAddress, final String passkey) throws DBusException { - - String agentPath = "/org/lejos/authenticate/" + getAdapterID() + "/" + deviceAddress.replace(':', '_'); - - dbusConn.exportObject(agentPath, new PinAgent(passkey)); - - //System.out.println("Calling CreatedPairedDevive on " + deviceAddress + " using agent: " + agentPath); - try { - adapter.CreatePairedDevice(deviceAddress, new Path(agentPath), ""); - return true; - } finally { - dbusConn.unExportObject(agentPath); - } - } - - public String getAdapterID() { - return hciID(adapterPath.getPath()); - } - - private String hciID(String adapterPath) { - final String bluezPath = "/org/bluez/"; - String path; - if (adapterPath.startsWith(bluezPath)) { - path = adapterPath.substring(bluezPath.length()); - } else { - path = adapterPath; - } - int lastpart = path.lastIndexOf('/'); - if ((lastpart != -1) && (lastpart != path.length() -1)) { - return path.substring(lastpart + 1); - } else { - return path; - } - } - - public List listAdapters() { - List a = new ArrayList(); - Path[] adapters = dbusManager.ListAdapters(); - if (adapters != null) { - for (int i = 0; i < adapters.length; i++) { - a.add(hciID(adapters[i].getPath())); - } - } - return a; - } - - public List listDevices() { - List a = new ArrayList(); - Path[] devices = adapter.ListDevices(); - for(Path device: devices) { - String dev = device.getPath(); - int ind = dev.indexOf("dev_"); - if (ind >= 0) a.add(dev.substring(ind+4).replace('_', ':')); - } - return a; - } - - /* - * (non-Javadoc) - * - * @see org.bluez.BlueZAPI#retrieveDevices(boolean) - */ - public List retrieveDevices(boolean preKnown) { - Path[] devices = adapter.ListDevices(); - List addresses = new Vector(); - if (devices != null) { - for (Path devicePath : devices) { - System.out.println("Path " + devicePath.getPath()); - try { - Device device = dbusConn.getRemoteObject("org.bluez", devicePath.getPath(), Device.class); - Map> properties = device.GetProperties(); - if (properties != null) { - String address = DBusProperties.getStringValue(properties, Device.Properties.Address); - boolean paired = DBusProperties.getBooleanValue(properties, Device.Properties.Paired, false); - boolean trusted = DBusProperties.getBooleanValue(properties, Device.Properties.Trusted, false); - if ((!preKnown) || paired || trusted) { - addresses.add(address); - } - } - } catch (DBusException e) { - System.out.println("can't get device " + devicePath + " exception" + e); - } - } - } - return addresses; - } - - public void removeAuthenticationWithRemoteDevice(String deviceAddress) throws DBusException { - Path devicePath = adapter.FindDevice(deviceAddress); - adapter.RemoveDevice(devicePath); - } - - public String getDeviceName(String deviceAddress) { - try { - Path devicePath = adapter.FindDevice(deviceAddress); - Device device = dbusConn.getRemoteObject("org.bluez", devicePath.getPath(), Device.class); - Map> properties = device.GetProperties(); - if (properties != null) { - String name = DBusProperties.getStringValue(properties, Device.Properties.Name); - return name; - } - } catch (DBusException e) { - System.out.println("Can't get property for " + deviceAddress + " " + e); - } - return ""; - } - - public int getDeviceClass(String deviceAddress) { - try { - Path devicePath = adapter.FindDevice(deviceAddress); - Device device = dbusConn.getRemoteObject("org.bluez", devicePath.getPath(), Device.class); - Map> properties = device.GetProperties(); - if (properties != null) { - int cod = DBusProperties.getIntValue(properties, Device.Properties.Class); - return cod; - } - } catch (DBusException e) { - System.out.println("Can't get property for " + deviceAddress + " " + e); - } - return 0; - } - - public void disconnect() - { - dbusConn.disconnect(); - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/dbus/DBusProperties.java b/ev3classes/src/main/java/lejos/internal/dbus/DBusProperties.java deleted file mode 100644 index abed1ff..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/DBusProperties.java +++ /dev/null @@ -1,148 +0,0 @@ -package lejos.internal.dbus; - -/** - * BlueCove - Java library for Bluetooth - * Copyright (C) 2009 Vlad Skarzhevskyy - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - * @author vlads - * @version $Id$ - */ - - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Map; - -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.UInt32; -import org.freedesktop.dbus.Variant; - -public abstract class DBusProperties { - - public interface PropertyEnum { - - } - - public enum DBusPropertyAccessType { - - READWRITE, - - READONLY; - } - - @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) - public @interface DBusProperty { - - /** - * The name of the Property. Defaults to the property or Enum name - */ - String name() default ""; - - /** - * The property type class. - */ - Class type() default void.class; - - DBusPropertyAccessType access() default DBusPropertyAccessType.READWRITE; - - } - - public interface PropertiesAccess extends DBusInterface { - - /** - * Returns all properties for the interface. See the properties section for available properties. - * - * @return - */ - public Map> GetProperties(); - - /** - * Changes the value of the specified property. Only properties that are listed a read-write are changeable. - * - * @param name - * @param value - */ - public void SetProperty(String name, Variant value); - } - - public static String getStringValue(PropertiesAccess dBusInterface, PropertyEnum propertyEnum) { - //TODO use type annotation - return getStringValue(dBusInterface.GetProperties(), propertyEnum); - } - - @SuppressWarnings("unchecked") - public static String getStringValue(Map> properties, PropertyEnum propertyEnum) { - if (properties == null) { - return null; - } - //TODO use type annotation - Variant value = (Variant)properties.get(getPropertyName(propertyEnum)); - if (value == null) { - return null; - } - return value.getValue(); - } - - public static boolean getBooleanValue(PropertiesAccess dBusInterface, PropertyEnum propertyEnum) { - //TODO use type annotation - return getBooleanValue(dBusInterface.GetProperties(), propertyEnum); - } - - public static boolean getBooleanValue(Map> properties, PropertyEnum propertyEnum) { - //TODO use type annotation - return (Boolean) properties.get(getPropertyName(propertyEnum)).getValue(); - } - - @SuppressWarnings("unchecked") - public static boolean getBooleanValue(Map> properties, PropertyEnum propertyEnum, boolean defaultValue) { - //TODO use type annotation - Variant value = (Variant)properties.get(getPropertyName(propertyEnum)); - if (value == null) { - return defaultValue; - } else { - return value.getValue(); - } - } - - public static Integer getIntValue(PropertiesAccess dBusInterface, PropertyEnum propertyEnum) { - //TODO use type annotation - return getIntValue(dBusInterface.GetProperties(), propertyEnum); - } - - @SuppressWarnings("unchecked") - public static Integer getIntValue(Map> properties, PropertyEnum propertyEnum) { - if (properties == null) { - return null; - } - //TODO use type annotation - Variant value = (Variant)properties.get(getPropertyName(propertyEnum)); - if (value == null) { - return null; - } - return value.getValue().intValue(); - } - - public static String getPropertyName(PropertyEnum propertyEnum) { - //TODO use name annotation - return propertyEnum.toString(); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/dbus/Device.java b/ev3classes/src/main/java/lejos/internal/dbus/Device.java deleted file mode 100644 index 80a4ae8..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/Device.java +++ /dev/null @@ -1,100 +0,0 @@ -package lejos.internal.dbus; -import lejos.internal.dbus.DBusProperties.DBusProperty; -import lejos.internal.dbus.DBusProperties.DBusPropertyAccessType; - -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.DBusInterfaceName; -import org.freedesktop.dbus.Path; -import org.freedesktop.dbus.UInt32; -@DBusInterfaceName("org.bluez.Device") -public interface Device extends DBusInterface, DBusProperties.PropertiesAccess { - - public static enum Properties implements DBusProperties.PropertyEnum { - /** - * The Bluetooth device address of the remote device. - */ - @DBusProperty(type = String.class, access = DBusPropertyAccessType.READONLY) - Address, - - /** - * The Bluetooth remote name. This value can not be changed. Use the - * Alias property instead. - */ - @DBusProperty(type = String.class, access = DBusPropertyAccessType.READONLY) - Name, - - /** - * Proposed icon name according to the freedesktop.org icon naming - * specification. - */ - @DBusProperty(type = String.class, access = DBusPropertyAccessType.READONLY) - Icon, - - /** The Bluetooth class of device of the remote device. */ - @DBusProperty(type = UInt32.class, access = DBusPropertyAccessType.READONLY) - Class, - - /** - * List of 128-bit UUIDs that represents the available remote services. - */ - @DBusProperty(type = String[].class, access = DBusPropertyAccessType.READONLY) - UUIDs, - - /** - * Indicates if the remote device is paired. - */ - @DBusProperty(type = boolean.class, access = DBusPropertyAccessType.READONLY) - Paired, - /** - * Indicates if the remote device is currently connected. A - * PropertyChanged signal indicate changes to this status. - */ - @DBusProperty(type = boolean.class, access = DBusPropertyAccessType.READONLY) - Connected, - - /** - * Indicates if the remote is seen as trusted. This setting can be - * changed by the application. - */ - @DBusProperty(type = boolean.class) - Trusted, - - /** - * The name alias for the remote device. The alias can be used to have a - * different friendly name for the remote device. - * - * In case no alias is set, it will return the remote device name. - * Setting an empty string as alias will convert it back to the remote - * device name. - * - * When reseting the alias with an empty string, the emitted - * PropertyChanged signal will show the remote name again. - */ - @DBusProperty(type = String.class) - Alias, - - /** - * List of device node object paths. - */ - @DBusProperty(type = Path[].class, access = DBusPropertyAccessType.READONLY) - Nodes, - - /** - * The object path of the adapter the device belongs to. - */ - @DBusProperty(type = Path.class, access = DBusPropertyAccessType.READONLY) - Adapter, - /** - * Set to true if the device only supports the pre-2.1 pairing - * mechanism. This property is useful in the Adapter.DeviceFound signal - * to anticipate whether legacy or simple pairing will occur. - * - * Note that this property can exhibit false-positives in the case of - * Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry - * Response support. - */ - @DBusProperty(type = boolean.class, access = DBusPropertyAccessType.READONLY) - LegacyPairing - - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/dbus/Manager.java b/ev3classes/src/main/java/lejos/internal/dbus/Manager.java deleted file mode 100644 index f62676a..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/Manager.java +++ /dev/null @@ -1,13 +0,0 @@ -package lejos.internal.dbus; -import org.freedesktop.dbus.DBusInterface; -import org.freedesktop.dbus.DBusInterfaceName; -import org.freedesktop.dbus.Path; - -@DBusInterfaceName("org.bluez.Manager") -public interface Manager extends DBusInterface { - - public Path DefaultAdapter(); - - Path[] ListAdapters(); - -} diff --git a/ev3classes/src/main/java/lejos/internal/dbus/PinAgent.java b/ev3classes/src/main/java/lejos/internal/dbus/PinAgent.java deleted file mode 100644 index dbfc7ba..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/PinAgent.java +++ /dev/null @@ -1,50 +0,0 @@ -package lejos.internal.dbus; - -import org.freedesktop.dbus.Path; -import org.freedesktop.dbus.UInt32; - -public class PinAgent implements Agent { - - private String pin; - - public PinAgent(String pin) { - this.pin = pin; - } - - public void Authorize(Path device, String uuid) { - System.out.println("Authorize called"); - } - - public void ConfirmModeChange(String mode) { - System.out.println("ConfirmModeChange called"); - } - - public void DisplayPasskey(Path device, UInt32 passkey, byte entered) { - } - - public void RequestConfirmation(Path device, UInt32 passkey) { - } - - public UInt32 RequestPasskey(Path device) { - System.out.println("Request pass key called for " + device); - return null; - } - - public String RequestPinCode(Path device) { - System.out.println("Request pin code called for " + device); - return pin; - } - - public void Cancel() { - System.out.println("Cancel called"); - } - - public void Release() { - System.out.println("Release called"); - } - - public boolean isRemote() { - return false; - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/dbus/package-info.java b/ev3classes/src/main/java/lejos/internal/dbus/package-info.java deleted file mode 100644 index 62a21a0..0000000 --- a/ev3classes/src/main/java/lejos/internal/dbus/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Interface to the DBus subsystem, used for Bluetooth support. - */ -package lejos.internal.dbus; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3AnalogPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3AnalogPort.java deleted file mode 100644 index a044dc7..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3AnalogPort.java +++ /dev/null @@ -1,410 +0,0 @@ -package lejos.internal.ev3; - -import java.io.IOError; -import java.nio.ByteBuffer; - -import lejos.hardware.port.AnalogPort; -import lejos.internal.io.NativeDevice; -import lejos.utility.Delay; - -import com.sun.jna.Pointer; - -/** - * This class provides access to the EV3 Analog based sensor ports and other - * analog data sources. - * - * @author andy - * - */ -public class EV3AnalogPort extends EV3IOPort implements AnalogPort -{ - protected static final int ANALOG_SIZE = 5172; - protected static final int ANALOG_PIN1_OFF = 0; - protected static final int ANALOG_PIN6_OFF = 8; - protected static final int ANALOG_PIN5_OFF = 16; - protected static final int ANALOG_BAT_TEMP_OFF = 24; - protected static final int ANALOG_MOTOR_CUR_OFF = 26; - protected static final int ANALOG_BAT_CUR_OFF = 28; - protected static final int ANALOG_BAT_V_OFF = 30; - protected static final int ANALOG_ACTUAL_OFF = 4832; - protected static final int ANALOG_INDCM_OFF = 5156; - protected static final int ANALOG_INCONN_OFF = 5160; - protected static final int ANALOG_OUTDCM_OFF = 5164; - protected static final int ANALOG_OUTCONN_OFF = 5168; - protected static final int ANALOG_NXTCOL_OFF = 4856; - protected static final int ANALOG_NXTCOL_SZ = 72; - protected static final int ANALOG_NXTCOL_RAW_OFF = 54; - protected static NativeDevice dev; - protected static Pointer pAnalog; - protected static ByteBuffer inDcm; - protected static ByteBuffer inConn; - protected static ByteBuffer outDcm; - protected static ByteBuffer outConn; - protected static ByteBuffer shortVals; - - // NXT Color sensor stuff - // data ranges and limits - protected static final int ADVOLTS = 3300; - protected static final int ADMAX = 2703; - protected static final int MINBLANKVAL = (214 / (ADVOLTS / ADMAX)); - protected static final int SENSORMAX = ADMAX; - protected static final int SENSORRESOLUTION = 1023; - protected int[][] calData = new int[3][4]; - protected int[] calLimits = new int[2]; - protected short[] rawValues = new short[BLANK_INDEX + 1]; - protected short[] values = new short[BLANK_INDEX + 1]; - - - static { - initDeviceIO(); - } - - /** {@inheritDoc} - */ - @Override - public boolean open(int typ, int port, EV3Port ref) - { - if (!super.open(typ, port, ref)) - return false; - return true; - } - - - /** - * {@inheritDoc} - */ - @Override - public float getPin1() - { - return (float)shortVals.getShort(ANALOG_PIN1_OFF + port*2)*ADC_REF/ADC_RES; - } - - /** - * {@inheritDoc} - */ - @Override - public float getPin6() - { - return (float)shortVals.getShort(ANALOG_PIN6_OFF + port*2)*ADC_REF/ADC_RES; - } - - protected void getColorData() - { - //setPinMode(TYPE_COLORFULL); - Delay.msDelay(1000); - int offset = ANALOG_NXTCOL_OFF + port*ANALOG_NXTCOL_SZ; - for(int i = 0; i < calData.length; i++) - for(int j = 0; j < calData[0].length; j++) - { - calData[i][j] = shortVals.getInt(offset); - offset += 4; - //System.out.println("Cal data[" + i + "][" + j + "] " + calData[i][j]); - } - for(int i = 0; i < calLimits.length; i++) - { - calLimits[i] = shortVals.getShort(offset); - offset += 2; - //System.out.println("Cal limit[" + i + "] " + calLimits[i]); - } - - } - - protected void getRawValues() - { - int first = ANALOG_NXTCOL_OFF + port*ANALOG_NXTCOL_SZ + ANALOG_NXTCOL_RAW_OFF; - for(int i = 0; i < rawValues.length; i++) - rawValues[i] = shortVals.getShort(first + i*2); - - } - - /** - * This method accepts a set of raw values (in full color mode) and processes - * them using the calibration data to return standard RGB values between 0 and 255 - * @param vals array to return the newly calibrated data. - */ - private void calibrate(short[] vals) - { - // First select the calibration table to use... - int calTab; - int blankVal = rawValues[BLANK_INDEX]; - if (blankVal < calLimits[1]) - calTab = 2; - else if (blankVal < calLimits[0]) - calTab = 1; - else - calTab = 0; - // Now adjust the raw values - for (int col = RED_INDEX; col <= BLUE_INDEX; col++) - if (rawValues[col] > blankVal) - vals[col] = (short) (((rawValues[col] - blankVal) * calData[calTab][col]) >>> 16); - else - vals[col] = 0; - // finally adjust the blank value - if (blankVal > MINBLANKVAL) - blankVal -= MINBLANKVAL; - else - blankVal = 0; - blankVal = (blankVal * 100) / (((SENSORMAX - MINBLANKVAL) * 100) / ADMAX); - if (blankVal > SENSORRESOLUTION) - blankVal = SENSORRESOLUTION; - vals[BLANK_INDEX] = (short) ((blankVal * calData[calTab][BLANK_INDEX]) >>> 16); - } - - /** - * Return a single processed value. - * If in single color mode this returns a single reading as a percentage. If - * in full color mode it returns a Lego color value that identifies the - * color of the object in view. - * @return processed color value. - */ - protected short getColor() - { - calibrate(values); - int red = values[RED_INDEX]; - int blue = values[BLUE_INDEX]; - int green = values[GREEN_INDEX]; - int blank = values[BLANK_INDEX]; - // we have calibrated values, now use them to determine the color - - // The following algorithm comes from the 1.29 Lego firmware. - if (red > blue && red > green) - { - // red dominant color - if (red < 65 || (blank < 40 && red < 110)) - return BLACK; - if (((blue >> 2) + (blue >> 3) + blue < green) && - ((green << 1) > red)) - return YELLOW; - if ((green << 1) - (green >> 2) < red) - return RED; - if (blue < 70 || green < 70 || (blank < 140 && red < 140)) - return BLACK; - return WHITE; - } - else if (green > blue) - { - // green dominant color - if (green < 40 || (blank < 30 && green < 70)) - return BLACK; - if ((blue << 1) < red) - return YELLOW; - if ((red + (red >> 2)) < green || - (blue + (blue>>2)) < green ) - return GREEN; - if (red < 70 || blue < 70 || (blank < 140 && green < 140)) - return BLACK; - return WHITE; - } - else - { - // blue dominant color - if (blue < 48 || (blank < 25 && blue < 85)) - return BLACK; - if ((((red*48) >> 5) < blue && ((green*48) >> 5) < blue) || - ((red*58) >> 5) < blue || ((green*58) >> 5) < blue) - return BLUE; - if (red < 60 || green < 60 || (blank < 110 && blue < 120)) - return BLACK; - if ((red + (red >> 3)) < blue || (green + (green >> 3)) < blue) - return BLUE; - return WHITE; - } - } - - @Override - public void getFloats(float [] vals, int offset, int length) - { - if (length > 0) - { - getRawValues(); - int cnt = length; - if (cnt > rawValues.length) - cnt = rawValues.length; - for(int i = 0; i < cnt; i++) - vals[offset+i] = (float)rawValues[i]*ADC_REF/ADC_RES; - offset += cnt; - length -= cnt; - if (length > 0) - { - vals[offset] = getColor(); - } - } - } - - protected short getCurrentOffset() - { - return shortVals.getShort(ANALOG_ACTUAL_OFF + port*2); - } - - // The following methods provide compatibility with NXT sensors - - @Override - public boolean setType(int type) - { - boolean ret = true; - switch(type) - { - case TYPE_NO_SENSOR: - case TYPE_SWITCH: - case TYPE_TEMPERATURE: - case TYPE_CUSTOM: - case TYPE_ANGLE: - setPinMode(CMD_FLOAT); - break; - case TYPE_LIGHT_ACTIVE: - case TYPE_SOUND_DBA: - case TYPE_REFLECTION: - setPinMode(CMD_SET|CMD_PIN5); - break; - case TYPE_LIGHT_INACTIVE: - case TYPE_SOUND_DB: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED_9V: - setPinMode(CMD_SET|CMD_PIN1); - break; - case TYPE_COLORFULL: - case TYPE_COLORRED: - case TYPE_COLORGREEN: - case TYPE_COLORBLUE: - case TYPE_COLORNONE: - // Sensor type and pin modes are aligned - //System.out.println("Set type :" + type); - if (!setPinMode(type)) System.out.println("Failed to set mode"); - if (type == TYPE_COLORFULL) - // Read NXT color sensor calibration data - getColorData(); - break; - - default: - ret = false; - } - // wait for a new sample to avoid returning stale data - int curOffset = getCurrentOffset(); - while (curOffset == getCurrentOffset()) - Delay.msDelay(1); - return ret; - } - - - - // The following methods should arguably be in different class, but they - // share the same memory structures as those used for analog I/O. Perhaps - // we need to restructure at some point and mode them to a common private - // class. - - /** - * Return the analog voltage reading from pin 5 on the output port - * @param p the port number to return the reading for - * @return the voltage in mV - */ - protected static short getOutputPin5(int p) - { - return shortVals.getShort(ANALOG_PIN5_OFF + p*2); - } - - /** - * Return the battery temperature reading - * @return - */ - protected static short getBatteryTemperature() - { - return shortVals.getShort(ANALOG_BAT_TEMP_OFF); - } - - /** - * return the motor current - * @return - */ - protected static short getMotorCurrent() - { - return shortVals.getShort(ANALOG_MOTOR_CUR_OFF); - } - - /** - * return the battery current - * @return - */ - protected static short getBatteryCurrent() - { - return shortVals.getShort(ANALOG_BAT_CUR_OFF); - } - - /** - * return the battery voltage - * @return - */ - protected static short getBatteryVoltage() - { - return shortVals.getShort(ANALOG_BAT_V_OFF); - } - - /** - * get the type of the port - * @param port - * @return - */ - protected static int getPortType(int port) - { - if (port > PORTS || port < 0) - return CONN_ERROR; - return inConn.get(port); - } - - /** - * Get the type of analog sensor (if any) attached to the port - * @param port - * @return - */ - protected static int getAnalogSensorType(int port) - { - if (port > PORTS || port < 0) - return CONN_ERROR; - return inDcm.get(port); - } - - - /** - * get the type of the motor port - * @param port - * @return - */ - protected static int getMotorPortType(int port) - { - if (port > MOTORS || port < 0) - return CONN_ERROR; - return outConn.get(port); - } - - /** - * Get the type of analog sensor (if any) attached to the port - * @param port - * @return - */ - protected static int getMotorType(int port) - { - if (port > MOTORS || port < 0) - return CONN_ERROR; - return outDcm.get(port); - } - - - private static void initDeviceIO() - { - try { - dev = new NativeDevice("/dev/lms_analog"); - pAnalog = dev.mmap(ANALOG_SIZE); - } catch (IOError e) - { - throw new UnsupportedOperationException("Unable to access EV3 hardware. Is this an EV3?", e); - } - inDcm = pAnalog.getByteBuffer(ANALOG_INDCM_OFF, PORTS); - inConn = pAnalog.getByteBuffer(ANALOG_INCONN_OFF, PORTS); - outDcm = pAnalog.getByteBuffer(ANALOG_OUTDCM_OFF, PORTS); - outConn = pAnalog.getByteBuffer(ANALOG_OUTCONN_OFF, PORTS); - shortVals = pAnalog.getByteBuffer(0, ANALOG_SIZE); - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Audio.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Audio.java deleted file mode 100644 index 7686222..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Audio.java +++ /dev/null @@ -1,565 +0,0 @@ -package lejos.internal.ev3; - - -import java.io.*; - -import lejos.hardware.Audio; -import lejos.internal.io.NativeDevice; -import lejos.internal.io.SystemSettings; -import lejos.utility.Delay; - -/** - * EV3 sound routines. - * - */ -public class EV3Audio implements Audio -{ - - private static final int RIFF_HDR_SIZE = 44; - private static final int RIFF_RIFF_SIG = 0x52494646; - private static final int RIFF_WAVE_SIG = 0x57415645; - private static final int RIFF_FMT_SIG = 0x666d7420; - private static final short RIFF_FMT_PCM = 0x0100; - private static final short RIFF_FMT_1CHAN = 0x0100; - private static final short RIFF_FMT_8BITS = 0x0800; - private static final short RIFF_FMT_16BITS = 0x1000; - private static final int RIFF_DATA_SIG = 0x64617461; - - private static final int PCM_BUFFER_SIZE = 8*1024; - - public static final String VOL_SETTING = "lejos.volume"; - - private static int masterVolume = 0; - - private static NativeDevice dev = new NativeDevice("/dev/lms_sound"); - private static final byte OP_BREAK = 0; - private static final byte OP_TONE = 1; - private static final byte OP_PLAY = 2; - private static final byte OP_REPEAT = 3; - private static final byte OP_SERVICE = 4; - private static final EV3Audio singleton = new EV3Audio(); - private int PCMSampleSize = 0; - private byte[] PCMBuffer; - - /** - * Static constructor to force loading of system settings - */ - static { - singleton.loadSettings(); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() {singleton.endPCMPlayback();} - }); - } - - private EV3Audio() - { - } - - public static Audio getAudio() - { - return singleton; - } - - private static int C2 = 523; - - /** - * Play a system sound. - * - * - * - * - * - * - * - *
    aCodeResulting Sound
    0short beep
    1double beep
    2descending arpeggio
    3ascending arpeggio
    4long, low buzz
    - */ - public void systemSound(int aCode) - { - if (aCode == BEEP) - playTone(600, 200); - else if (aCode == DOUBLE_BEEP) - { - playTone(600, 150); - Delay.msDelay(50); - playTone(600, 150); - } - else if (aCode == ASCENDING)// C major arpeggio - for (int i = 4; i < 8; i++) - { - playTone(C2 * i / 4, 100); - } - else if (aCode == DESCENDING) - for (int i = 7; i > 3; i--) - { - playTone(C2 * i / 4, 100); - } - else if (aCode == BUZZ) - { - playTone(100, 500); - } - } - - - /** - * Plays a tone, given its frequency and duration. - * @param aFrequency The frequency of the tone in Hertz (Hz). - * @param aDuration The duration of the tone, in milliseconds. - * @param aVolume The volume of the playback 100 corresponds to 100% - */ - static void playFreq(int aFrequency, int aDuration, int aVolume) - { - if (aVolume >= 0) - aVolume = (aVolume*masterVolume)/100; - else - aVolume = -aVolume; - byte[] cmd = new byte[6]; - cmd[0] = OP_TONE; - cmd[1] = (byte) aVolume; - cmd[2] = (byte) aFrequency; - cmd[3] = (byte) (aFrequency >> 8); - cmd[4] = (byte) aDuration; - cmd[5] = (byte) (aDuration >> 8); - dev.write(cmd, cmd.length); - } - - - /** - * Plays a tone, given its frequency and duration. - * @param aFrequency The frequency of the tone in Hertz (Hz). - * @param aDuration The duration of the tone, in milliseconds. - * @param aVolume The volume of the playback 100 corresponds to 100% - */ - public void playTone(int aFrequency, int aDuration, int aVolume) - { - playFreq(aFrequency, aDuration, aVolume); - Delay.msDelay(aDuration); - } - - - public void playTone(int freq, int duration) - { - playTone(freq, duration, VOL_MAX); - } - - - - /** - * Read an LSB format - * @param d stream to read from - * @return the read int - * @throws java.io.IOException - */ - private int readLSBInt(DataInputStream d) throws IOException - { - int val = d.readByte() & 0xff; - val |= (d.readByte() & 0xff) << 8; - val |= (d.readByte() & 0xff) << 16; - val |= (d.readByte() & 0xff) << 24; - return val; - } - - /** - * Prepare the sound device to play PCM samples. - * @param sampleSize number of bits per sample - * @param sampleRate number of samples per second - * @param vol playback volume - */ - public synchronized void startPCMPlayback(int sampleSize, int sampleRate, int vol) - { - if (sampleSize != 8 && sampleSize != 16) - throw new UnsupportedOperationException("Only 8bit and 16bit samples supported size is " + sampleSize); - if (sampleRate < 8000 || sampleRate > 48000) - throw new UnsupportedOperationException("Sample rate must be between 8KHz and 48KHz"); - // save sample size for later - PCMSampleSize = sampleSize; - PCMBuffer = new byte[PCM_BUFFER_SIZE+1]; - if (vol >= 0) - vol = (vol*masterVolume)/100; - else - vol = -vol; - // get ready to play, set the volume - byte [] buf = new byte[6]; - buf[0] = OP_PLAY; - buf[1] = (byte)vol; - buf[2] = (byte) sampleRate; - buf[3] = (byte) (sampleRate >> 8); - buf[4] = (byte) (sampleRate >> 16); - buf[5] = (byte) (sampleRate >> 24); - dev.write(buf, 6); - } - - /** - * Cease the playing of PCM samples - */ - public synchronized void endPCMPlayback() - { - // are we playing? - if (PCMSampleSize == 0) - return; - PCMSampleSize = 0; - byte [] buf = new byte[6]; - buf[0] = OP_BREAK; - dev.write(buf, 1); - PCMBuffer = null; - } - - /** - * Helper method write the PCM data to the sound device. It is assumed that the buffer contains - * extra space for the command byte. - * @param buffer - * @param cnt - */ - private synchronized int writePCMBuffer(byte[] buf, int dataLen) - { - // check for playback aborted - if (PCMSampleSize == 0) return -1; - int offset = 0; - while (offset < dataLen) - { - buf[offset] = OP_SERVICE; - int len = dataLen - offset; - int written = dev.write(buf, offset, len + 1); - if (written < 0) return -1; - if (written < (len + 1)) - { - Delay.msDelay(5); - } - offset += written; - } - return dataLen; - } - - public void writePCMSamples(byte[] data, int offset, int dataLength) - { - if (PCMSampleSize == 0) - throw new UnsupportedOperationException("Sample size not set did you call startPCMPlayback"); - if (PCMSampleSize == 8) - { - // non native sample size need to convert - while (offset < dataLength) - { - int len = dataLength - offset; - if (len > PCM_BUFFER_SIZE/2) - len = PCM_BUFFER_SIZE/2; - int outOffset = 1; - for(int i = 0; i < len; i++) - { - // 8 bit data is unsigned with a 128 offset, need to convert to 16 bit signed - int sample = (((int)data[i] & 0xff) - 128) << 8; - PCMBuffer[outOffset++] = (byte)sample; - PCMBuffer[outOffset++] = (byte)(sample >> 8); - } - if (writePCMBuffer(PCMBuffer, len*2) < 0) return; - offset += len; - } - } - else - { - // native format - while (offset < dataLength) - { - int len = dataLength - offset; - if (len > PCM_BUFFER_SIZE) - len = PCM_BUFFER_SIZE; - System.arraycopy(data, offset, PCMBuffer, 1, len); - if (writePCMBuffer(PCMBuffer, len) < 0) return; - offset += len; - } - - } - - } - - - /** - * Play a wav file - * @param file the 8/16-bit PWM (WAV) sample file - * @param vol the volume percentage 0 - 100 - * @return 0 if the sample has been played or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file, int vol) - { - // First check that we have a wave file. File must be at least 44 bytes - // in size to contain a RIFF header. - if (file.length() < RIFF_HDR_SIZE) - return -9; - // Now check for a RIFF header - FileInputStream f = null; - DataInputStream d = null; - boolean playing = false; - try - { - f = new FileInputStream(file); - d = new DataInputStream(new BufferedInputStream(f)); - - if (d.readInt() != RIFF_RIFF_SIG) - return -1; - // Skip chunk size - d.readInt(); - // Check we have a wave file - if (d.readInt() != RIFF_WAVE_SIG) - return -2; - if (d.readInt() != RIFF_FMT_SIG) - return -3; - // Now check that the format is PCM, Mono 8 bits. Note that these - // values are stored little endian. - int sz = readLSBInt(d); - if (d.readShort() != RIFF_FMT_PCM) - return -4; - if (d.readShort() != RIFF_FMT_1CHAN) - return -5; - int sampleRate = readLSBInt(d); - if (sampleRate > 48000) - return -7; - d.readInt(); - d.readShort(); - short sampleSize = d.readShort(); - if (sampleSize != RIFF_FMT_16BITS && sampleSize != RIFF_FMT_8BITS) - return -6; - playing = true; - // Skip any data in this chunk after the 16 bytes above - sz -= 16; - while (sz-- > 0) - d.readByte(); - startPCMPlayback(sampleSize == RIFF_FMT_16BITS ? 16 : 8, sampleRate, vol); - playing = true; - int dataLen; - // Skip/process chunks until we hit eof! - for(;;) - { - int chunk = d.readInt(); - dataLen = readLSBInt(d); - if (chunk == RIFF_DATA_SIG) - { - int read; - if (sampleSize == RIFF_FMT_16BITS) - { - // optimized case for native format - while(dataLen > 0 && (read = d.read(PCMBuffer, 1, (PCMBuffer.length - 1 < dataLen ? PCMBuffer.length -1 : dataLen))) > 0) - { - writePCMBuffer(PCMBuffer, read); - dataLen -= read; - } - } - else - { - // need to handle data conversion - byte[] data = new byte[PCM_BUFFER_SIZE/2]; - while(dataLen > 0 && (read = d.read(data, 0, (data.length < dataLen ? data.length : dataLen))) > 0) - { - writePCMSamples(data, 0, read); - dataLen -= read; - } - } - } - else - { - // Skip to the start of the next chunk - while(dataLen-- > 0) - d.readByte(); - } - } - } - catch (EOFException e) - { - return 0; - } - catch (IOException e) - { - return -1; - } - finally - { - try { - if (d != null) - d.close(); - if (f != null) - f.close(); - if (playing) - endPCMPlayback(); - } - catch (IOException e) - { - return -1; - } - } - } - - - /** - * Play a wav file - * @param file the 8-bit PWM (WAV) sample file - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file) - { - return playSample(file, VOL_MAX); - } - - - /** - * Queue a series of PCM samples to play at the - * specified volume and sample rate. - * - * @param data Buffer containing the samples - * @param offset Offset of the first sample in the buffer - * @param len Number of bytes to queue - * @param sampleRate Sample rate - * @param vol playback volume - * @return Number of bytes actually queued - */ - public int playSample(byte [] data, int offset, int len, int sampleRate, int vol) - { - startPCMPlayback(8, sampleRate, vol); - writePCMSamples(data, offset, len); - endPCMPlayback(); - return len; - } - - - - private int waitUntil(int t) - { - int t2; - while ((t2 = (int) System.currentTimeMillis()) < t) - Thread.yield(); - return t2; - } - - /** - * Play a note with attack, decay, sustain and release shape. This function - * allows the playing of a more musical sounding note. It uses a set of - * supplied "instrument" parameters to define the shape of the notes - * envelope. - * @param inst Instrument definition - * @param freq The note to play (in Hz) - * @param len The duration of the note (in ms) - */ - public void playNote(int[] inst, int freq, int len) - { - // Generate an envelope controlled note. The instrument array contains - // the shape of the envelope. The attack period, the decay period the - // level to decay to and the level to decay to during the sustain part - // of the note finally the length of the actual release period. All - // periods are given in 2000th of a second units. This is because the - // generation of a tone using the playTone function will often take - // more than 1ms to execute. This means that the minimum tone segment - // that we can reliably generate is 2ms and so we use this unit as the - // basis of note generation. - int segLen = inst[0]; - // All volume settings are scaled by 100. - int step = 9000 / segLen; - int vol = 100; - int oldVol = 0; - //System.out.println("Start playing"); - // We do not really have fine grained enough timing so try and keep - // things aligned as closely as possible to a tick by waiting here - // before we start for the next tick. - int t = waitUntil((int) System.currentTimeMillis() + 1); - // Generate the attack profile from 20 to full volume - playFreq(freq, len+2000, vol / 100); - len /= 2; - for (int i = 0; i < segLen; i++) - { - vol += step; - if (oldVol != vol/100) - { - playFreq(freq, 100, vol / 100); - oldVol = vol/100; - } - t = waitUntil(t + 2); - } - len -= segLen; - // Now do the decay - segLen = inst[1]; - if (segLen > 0) - { - step = inst[2] / segLen; - for (int i = 0; i < segLen; i++) - { - vol -= step; - if (oldVol != vol/100) - { - playFreq(freq, 100, vol / 100); - oldVol = vol/100; - } - t = waitUntil(t + 2); - } - len -= segLen; - } - segLen = inst[4]; - len -= segLen; - // adjust length of the sustain and possibly the release to match the - // requested note length - if (len > 0) - { - step = inst[3] / len; - for (int i = 0; i < len; i++) - { - vol -= step; - if (oldVol != vol/100) - { - playFreq(freq, 100, vol / 100); - oldVol = vol/100; - } - t = waitUntil(t + 2); - } - } - else - segLen += len; - // Finally do the release - if (segLen > 0) - { - //System.out.println("RVol: " +vol); - step = (vol - 100) / segLen; - for (int i = 0; i < segLen; i++) - { - vol -= step; - if (oldVol != vol/100) - { - playFreq(freq, 100, vol / 100); - oldVol = vol/100; - } - t = waitUntil(t + 2); - } - } - byte []cmd = new byte[1]; - cmd[0] = OP_BREAK; - dev.write(cmd, 1); - } - - /** - * Set the master volume level - * @param vol 0-100 - */ - public void setVolume(int vol) - { - if (vol > VOL_MAX) vol = VOL_MAX; - if (vol < 0) vol = 0; - masterVolume = vol; - } - - /** - * Get the current master volume level - * @return the current master volume 0-100 - */ - public int getVolume() - { - return masterVolume; - } - - /** - * Load the current system settings associated with this class. Called - * automatically to initialize the class. May be called if it is required - * to reload any settings. - */ - public void loadSettings() - { - masterVolume = SystemSettings.getIntSetting(VOL_SETTING, 80); - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Battery.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Battery.java deleted file mode 100644 index 308e0df..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Battery.java +++ /dev/null @@ -1,68 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.Power; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * Class which provides information about the EV3 battery.
    - * TODO: The motor current and battery temp. values do not seem to be valid. - * Check on other EV3s to see if they are different. - * @author andy - * - */ -public class EV3Battery implements Power -{ - protected final static float SHUNT_IN = 0.05f; - protected final static float AMP_CIN = 15.0f; - protected final static float SHUNT_OUT = 0.055f; - protected final static float AMP_COUT = 19.0f; - protected final static float VCE = 0.05f; - protected final static float AMP_VIN = 0.5f; - /** - * Convert from ADC reading to actual units. - * @param val - * @return - */ - protected float convert(int val) - { - return((float)val*EV3SensorConstants.ADC_REF)/(EV3SensorConstants.ADC_RES); - } - /** - * {@inheritDoc} - */ - @Override - public int getVoltageMilliVolt() - { - // TODO Auto-generated method stub - return (int)(getVoltage()*1000f); - } - - /** - * {@inheritDoc} - */ - @Override - public float getVoltage() - { - float CinV = convert(EV3AnalogPort.getBatteryCurrent())/AMP_CIN; - return convert(EV3AnalogPort.getBatteryVoltage())/AMP_VIN + CinV + VCE; - } - - /** - * {@inheritDoc} - */ - @Override - public float getBatteryCurrent() - { - return (convert(EV3AnalogPort.getBatteryCurrent())/AMP_CIN)/SHUNT_IN; - } - - /** - * {@inheritDoc} - */ - @Override - public float getMotorCurrent() - { - return (convert(EV3AnalogPort.getMotorCurrent())/AMP_COUT)/SHUNT_OUT; - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3ConfigurationPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3ConfigurationPort.java deleted file mode 100644 index 761f6df..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3ConfigurationPort.java +++ /dev/null @@ -1,86 +0,0 @@ -package lejos.internal.ev3; - -import java.io.IOError; - -import lejos.hardware.port.ConfigurationPort; -import lejos.hardware.sensor.EV3SensorConstants; -import lejos.internal.io.NativeDevice; -import lejos.utility.Delay; - -public class EV3ConfigurationPort extends EV3IOPort implements ConfigurationPort -{ - protected static NativeDevice dev; - - static { - initDeviceIO(); - } - - /** {@inheritDoc} - * Note that it can take up to two seconds for the identification data to be available - * after the port has been opened. - */ - @Override - public boolean open(int typ, int port, EV3Port ref) - { - if (!super.open(typ, port, ref)) - return false; - // enable automatic detection on this port - setPinMode(CMD_AUTOMATIC); - return true; - } - - - /** - * Get the type classification for the port. If a sensor is attached to the port - * this will identify the connection type (UART/IIC/Dumb/Output etc.) - * @return The type of the port. - */ - public int getPortType() - { - if (typ == EV3Port.MOTOR_PORT) - return EV3AnalogPort.getMotorPortType(port); - else - return EV3AnalogPort.getPortType(port); - } - - /** - * This function returns information on the sensor/motor that is attached to the - * specified port. Note that only very basic sensor identification information - * may be available for some sensor types. It may be necessary to actually open the - * sensor to allow it to be identified in further detail. - * @return the sensor type - */ - public int getDeviceType() - { - if (typ == EV3Port.MOTOR_PORT) - return EV3AnalogPort.getMotorType(port); - else - return EV3AnalogPort.getAnalogSensorType(port); - } - - - /** - * Set the basic operating mode of the various sensor pins to allow correct - * operation of the attached sensor. - * @param port port to set - * @param mode the pin mode to use. - */ - public static boolean setPortMode(int typ, int port, int mode) - { - //System.out.println("Set port mode " + port + " mode " + mode); - byte [] cmd = new byte[2]; - cmd[0] = (byte)(typ == EV3Port.MOTOR_PORT ? port + PORTS : port); - cmd[1] = (byte)mode; - return dev.write(cmd, cmd.length) >= 0; - } - - private static void initDeviceIO() - { - try { - dev = new NativeDevice("/dev/lms_dcm"); - } catch(IOError e) - { - throw new UnsupportedOperationException("Unable to access EV3 hardware. Is this an EV3?", e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3GraphicsLCD.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3GraphicsLCD.java deleted file mode 100644 index df7ade6..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3GraphicsLCD.java +++ /dev/null @@ -1,1070 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.Image; - -/** - * lcdui.graphics implementation for the EV3 LCD screen and in memory images. - * This class provides a sun-set of the standard JavaME graphics class. In - * particular it does not implement clipping. There are also several additional - * non-standard methods to allow easier use of images, alow access to inverse - * text, and allow the use of raster operations. Some of the standard limitations - * (like not allowing copyArea of the screen), are not enforced. - * @author Brian Bagnall and Andy - * - */ -public class EV3GraphicsLCD extends EV3LCD implements GraphicsLCD -{ - /** drawArc and fillArc accuracy parameter */ - private static final int ARC_ACC = 5; - private int rgbColor = BLACK; - private int textRop = ROP_OR; - private int pixelRop = ROP_SET; - private int strokeStyle = SOLID; - private Font font = Font.getDefaultFont(); - private byte[] imageBuf; - private int width; - private int height; - private int transX = 0; - private int transY = 0; - - /** - * Default constructor returns a context that can be used to access the NXT - * LCD display. - */ - public EV3GraphicsLCD(String layerName) - { - super(layerName); - imageBuf = getDisplay(); - width = SCREEN_WIDTH; - height = SCREEN_HEIGHT; - } - - /** - * Create a graphics object that can be used to access the supplied memory - * buffer. - * @param data The memory buffer - * @param width width of the buffer - * @param height height of the buffer - */ - - public EV3GraphicsLCD(byte[] data, int width, int height) - { - imageBuf = data; - this.width = width; - this.height = height; - } - - /** - * Adjust the x co-ordinate to use the translation and anchor values. - * @param x Original value - * @param w width of the item. - * @param anchor anchor parameter - * @return updated x value. - */ - private int adjustX(int x, int w, int anchor) - { - x += transX; - switch (anchor & (LEFT | RIGHT | HCENTER)) - { - case LEFT: - break; - case RIGHT: - x -= w; - break; - case HCENTER: - x -= (w >> 1); - break; - } - return x; - } - - /** - * Adjust the y co-ordinate to use the translation and anchor values. - * @param y Original value - * @param h height of the item. - * @param anchor anchor parameter - * @return updated y value. - */ - private int adjustY(int y, int h, int anchor) - { - y += transY; - switch (anchor & (TOP | BOTTOM | VCENTER)) - { - case TOP: - break; - case BOTTOM: - y -= h; - break; - case VCENTER: - y -= (h >> 1); - break; - } - return y; - } - - /* The following are non standard functions. What should we do with them */ - /** - * Return the width of the associated drawing surface. - *
    Note: This is a non standard method. - * @return width of the surface - */ - public int getWidth() - { - return width; - } - - /** - * Return the height of the associated drawing surface. - *
    Note: This is a non standard method. - * @return height of the surface. - */ - public int getHeight() - { - return height; - } - - /** - * Draws the specified String using the current font and color. x and y - * give the location of the anchor point. Additional method to allow for - * the easy use of inverted text. In this case the area below the string - * is drawn in the current color, before drawing the text in the "inverted" - * color. - *
    Note: This is a non standard method. - * @param str the String to be drawn - * @param x the x coordinate of the anchor point - * @param y the y coordinate of the anchor point - * @param anchor the anchor point for positioning the text - * @param inverted true to invert the text display. - */ - public void drawString(String str, int x, int y, int anchor, boolean inverted) - { - x += transX; - y += transY; - if (anchor == 0) - anchor = TOP | LEFT; - if ((anchor & LEFT) == 0) - { - int strWidth = font.stringWidth(str); - if ((anchor & RIGHT) != 0) - x -= strWidth; - else if ((anchor & HCENTER) != 0) - x -= (strWidth / 2); - } - - if ((anchor & TOP) == 0) - { - if ((anchor & BASELINE) != 0) - y -= font.getBaselinePosition(); - else if ((anchor & BOTTOM) != 0) - y -= font.getHeight(); - } - int gw = font.glyphWidth; - int gh = font.height; - int rop = textRop; - int cellWidth = font.width; - byte[] glyphs = font.glyphs; - int span = gw * font.glyphCount; - int first = font.firstChar; - char[] strData = str.toCharArray(); - if (inverted) - { - // draw background and use inverted rop... - bitBlt(null, width, height, 0, 0, imageBuf, width, height, x, y, cellWidth * strData.length, gh, pixelRop); - rop = (rgbColor == WHITE ? ROP_OR : ROP_ANDINVERTED); - } - for (int i = 0; i < strData.length; i++) - bitBlt(glyphs, span, gh, gw * (strData[i] - first), 0, imageBuf, width, height, x + i * cellWidth, y, gw, gh, rop); - } - - /** - * Draw the specified image to the graphics surface, using the supplied rop. - *
    Note: This is a non standard method. - * Added because without it, it is very - * hard to invert/manipulate an image, or screen region - * @param src image to draw (may be null for ops that do not require input. - * @param sx x offset in the source - * @param sy y offset in the source - * @param w width of area to draw - * @param h height of area to draw. - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @param rop drawing operation. - * @see Image - */ - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, int y, int anchor, int rop) - { - x = adjustX(x, w, anchor); - y = adjustY(y, h, anchor); - if (src == null) - bitBlt(imageBuf, width, height, sx, sy, imageBuf, width, height, x, y, w, h, rop); - else - bitBlt(src.getData(), src.getWidth(), src.getHeight(), sx, sy, imageBuf, width, height, x, y, w, h, rop); - } - - /** - * Draw the specified region of the source image to the graphics surface - * after applying the requested transformation, use the supplied rop. - *
    NOTE: When calculating the anchor point this method assumes that - * a transformed version of the source width/height should be used. - * @param src The source image - * @param sx x coordinate of the region - * @param sy y coordinate of the region - * @param w width of the region - * @param h height of the region - * @param transform the required transform - * @param x x coordinate of the anchor point - * @param y y coordinate of the anchor point - * @param anchor type of anchor - * @param rop raster operation used to draw the output. - */ - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int transform, int x, int y, int anchor, int rop) - { - // Check for common optimized case... - if (transform == 0) - { - drawRegionRop(src, sx, sy, w, h, x, y, anchor, rop); - return; - } - - byte[] inData = src.getData(); - int inWidth = src.getWidth(); - int inHeight = src.getHeight(); - - // Transform matrix - int x1 = 1; - int y1 = 0; - int x2 = 0; - int y2 = 1; - // Transformed version of width/height. - int ow = w; - int oh = h; - switch (transform) - { - case TRANS_MIRROR: - x1 = -1; - break; - case TRANS_MIRROR_ROT180: - y2 = -1; - break; - case TRANS_MIRROR_ROT270: - x1 = 0; - y1 = 1; - x2 = 1; - y2 = 0; - ow = h; - oh = w; - break; - case TRANS_MIRROR_ROT90: - x1 = 0; - y1 = -1; - x2 = -1; - y2 = 0; - ow = h; - oh = w; - break; - case TRANS_ROT180: - x1 = -1; - y2 = -1; - break; - case TRANS_ROT270: - x1 = 0; - y1 = 1; - x2 = -1; - y2 = 0; - ow = h; - oh = w; - break; - case TRANS_ROT90: - x1 = 0; - y1 = -1; - x2 = 1; - y2 = 0; - ow = h; - oh = w; - break; - } - // Sort out the anchor point. - x = adjustX(x, ow, anchor); - y = adjustY(y, oh, anchor); - - // perform the transformation. - // We rotate around the centre point - int cx = (w + 1) / 2; - int cy = (h + 1) / 2; - // Setup the input centre point - int sxbase = sx + cx; - int sybase = sy + cy; - // Setup the output centre point. Note that we use transformed rounding. - // If we don't do this the for even widths/heights we end up with a - // on symetric rotation. - int xbase = x + (ow + x1 + y1) / 2; - int ybase = y + (oh + x2 + y2) / 2; - // Now loop through the input region... - int iy = -cy; - int iye = iy + h; - while (iy < iye) - { - int iyy1 = iy * y1; - int iyy2 = iy * y2; - int ix = -cx; - int ixe = ix + w; - while (ix < ixe) - { - int ox = ix * x1 + iyy1 + xbase; - int oy = ix * x2 + iyy2 + ybase; - bitBlt(inData, inWidth, inHeight, sxbase + ix, sybase + iy, imageBuf, width, height, ox, oy, 1, 1, rop); - ix++; - } - iy++; - } - - } - - /** - * Clear the graphics surface to white. - */ - public void clear() - { - bitBlt(imageBuf, width, height, 0, 0, imageBuf, width, height, 0, 0, width, height, ROP_CLEAR); - } - - /** - * Return the currently selected font object. - * @return Current font. - */ - public Font getFont() - { - return font; - } - - public void setFont(Font f) - { - font = f; - } - - /** - * Returns the actual color that will be used on the display if the specified - * color is requested. On the EV3 LCD and value that is not black will be - * treated as white. - * @param color - * @return the display color - */ - public int getDisplayColor(int color) - { - return color == BLACK ? BLACK : WHITE; - } - - /** - * Set the current drawing color. The value is in the format 0x00RRGGBB. - * NOTE. Currently only black and white is supported. any non black color - * is treated as white! - * @param rgb new color. - */ - public void setColor(int rgb) - { - rgbColor = rgb; - if (rgbColor == BLACK) - { - pixelRop = ROP_SET; - textRop = ROP_OR; - } - else - { - pixelRop = ROP_CLEAR; - textRop = ROP_ANDINVERTED; - } - } - - /** - * Sets the current color to the specified RGB values. - * @param red the red component - * @param green the green component - * @param blue the blue - * @throws IllegalArgumentException if any of the color components - * are outside of range 0-255 - * @see #getColor - */ - public void setColor(int red, int green, int blue) - { - if ((red < 0) || (red > 255) - || (green < 0) || (green > 255) - || (blue < 0) || (blue > 255)) - { - throw new IllegalArgumentException("bad color value"); - } - setColor((red << 16) | (green << 8) | blue); - } - - /** - * Return the current rgb color. - * @return current color. - */ - public int getColor() - { - return rgbColor; - } - - /** - * Gets the red value of color. - * @return value in range 0-255 - * @see #setColor(int, int, int) - */ - public int getRedComponent() - { - return (rgbColor >> 16) & 0xff; - } - - /** - * Gets the green value of color. - * @return integer value in range 0-255 - * @see #setColor(int, int, int) - */ - public int getGreenComponent() - { - return (rgbColor >> 8) & 0xff; - } - - /** - * Gets the blue value of color. - * @return integer value in range 0-255 - * @see #setColor(int, int, int) - */ - public synchronized int getBlueComponent() - { - return rgbColor & 0xff; - } - - /** - * Draws the specified String using the current font and color. x and y - * give the location of the anchor point. - * @param str the String to be drawn - * @param x the x coordinate of the anchor point - * @param y the y coordinate of the anchor point - * @param anchor the anchor point for positioning the text - */ - public void drawString(String str, int x, int y, int anchor) - { - drawString(str, x, y, anchor, false); - } - - /** - * Draw a substring to the graphics surface using the current color. - * @param str the base string - * @param offset the start of the sub string - * @param len the length of the sub string - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawSubstring(String str, int offset, int len, - int x, int y, int anchor) - { - // will throw NullPointerException - int strLen = str.length(); - if ((offset < 0) || (offset > strLen) - || (len < 0) || (len > strLen) - || ((offset + len) < 0) || ((offset + len) > strLen)) - { - throw new StringIndexOutOfBoundsException(); - } - - drawString(str.substring(offset, offset + len), x, y, anchor); - } - - /** - * Draw a single character to the graphics surface using the current color. - * @param character the character to draw - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawChar(char character, int x, int y, int anchor) - { - drawString(new String(new char[] - { - character - }), x, y, anchor); - } - - /** - * Draw a series of characters to the graphics surface using the current color. - * @param data the characters - * @param offset the start of the characters to be drawn - * @param length the length of the character string to draw - * @param x the x coordinate of the anchor point - * @param y the x coordinate of the anchor point - * @param anchor the anchor point used to position the text. - */ - public void drawChars(char[] data, int offset, int length, - int x, int y, int anchor) - { - - - // this will throw NullPointerException if data == null - int chLen = data.length; - - if ((offset < 0) || (offset > chLen) - || (length < 0) || (length > chLen) - || ((offset + length) < 0) || ((offset + length) > chLen)) - { - throw new ArrayIndexOutOfBoundsException(); - } - - drawString(new String(data, offset, length), x, y, anchor); - - } - - /** - * Draw the specified region of the supplied image to the graphics surface. - * NOTE: Transforms are not currently supported. - * @param src image to draw (may be null for ops that do not require input. - * @param sx x offset to the region - * @param sy y offset to the region - * @param w width of the region - * @param h height of the region - * @param transform - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @see Image - */ - 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); - } - - /** - * Draw the specified image to the graphics surface, using the supplied rop. - * @param src image to draw (may be null for ops that do not require input. - * @param x destination - * @param y destination - * @param anchor location of the anchor point - * @see Image - */ - public void drawImage(Image src, int x, int y, int anchor) - { - drawRegionRop(src, 0, 0, src.getWidth(), src.getHeight(), x, y, anchor, ROP_COPY); - } - - /** - * Method to set a pixel to screen. - * @param x the x coordinate - * @param y the y coordinate - */ - private void setPixel(int x, int y) - { - bitBlt(imageBuf, width, height, 0, 0, imageBuf, width, height, x, y, 1, 1, pixelRop); - } - - /** - * Draw a line between the specified points, using the current color and style. - * @param x0 x start point - * @param y0 y start point - * @param x1 x end point - * @param y1 y end point - */ - public void drawLine(int x0, int y0, int x1, int y1) - { - drawLine(x0, y0, x1, y1, strokeStyle); - } - - private void drawLine(int x0, int y0, int x1, int y1, int style) - { - // Uses Bresenham's line algorithm - y0 += transY; - y1 += transY; - x0 += transX; - x1 += transX; - int dy = y1 - y0; - int dx = x1 - x0; - int stepx, stepy; - boolean skip = false; - if (style == SOLID && (dx == 0 || dy == 0)) - { - // Special case horizontal and vertical lines - if (dx <= 0) - { - x0 = x1; - dx = -dx; - } - if (dy <= 0) - { - y0 = y1; - dy = -dy; - } - bitBlt(imageBuf, width, height, x0, y0, imageBuf, width, height, x0, y0, - dx + 1, dy + 1, (rgbColor == BLACK ? ROP_SET : ROP_CLEAR)); - return; - } - if (dy < 0) - { - dy = -dy; - stepy = -1; - } else - { - stepy = 1; - } - if (dx < 0) - { - dx = -dx; - stepx = -1; - } else - { - stepx = 1; - } - dy <<= 1; // dy is now 2*dy - dx <<= 1; // dx is now 2*dx - - setPixel(x0, y0); - if (dx > dy) - { - int fraction = dy - (dx >> 1); // same as 2*dy - dx - while (x0 != x1) - { - if (fraction >= 0) - { - y0 += stepy; - fraction -= dx; // same as fraction -= 2*dx - } - x0 += stepx; - fraction += dy; // same as fraction -= 2*dy - if ((style == SOLID) || !skip) - setPixel(x0, y0); - skip = !skip; - } - } else - { - int fraction = dx - (dy >> 1); - while (y0 != y1) - { - if (fraction >= 0) - { - x0 += stepx; - fraction -= dy; - } - y0 += stepy; - fraction += dx; - if ((style == SOLID) || !skip) - setPixel(x0, y0); - skip = !skip; - } - } - } - - /** - * Draw an arc, using the current color and style. - * @param x - * @param y - * @param width - * @param height - * @param startAngle - * @param arcAngle - */ - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) - { - drawArc(x, y, width, height, startAngle, arcAngle, strokeStyle, false); - } - - /** - * Draw a filled arc, using the current color. - * @param x - * @param y - * @param width - * @param height - * @param startAngle - * @param arcAngle - */ - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) - { - // drawArc is for now only SOLID - drawArc(x, y, width, height, startAngle, arcAngle, SOLID, true); - } - - private void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle, - int style, boolean fill) - { - // Scale up width and height to create more accurate ellipse form - int xscale = (width < height) ? ARC_ACC : ((ARC_ACC * width + (width >> 1)) / height); - int yscale = (width < height) ? ((ARC_ACC * height + (height >> 1)) / width) : ARC_ACC; - x += transX; - y += transY; - // Calculate x, y center and radius from upper left corner - int x0 = x + (width >> 1); - int y0 = y + (height >> 1); - int radius = (width < height) ? (width >> 1) : (height >> 1); - if (arcAngle >= 360 || arcAngle <= -360) - { - drawTheCircle(radius, style, fill, xscale, yscale, x0, y0); - return; - } - - while (startAngle < 0) - startAngle += 360; - while (startAngle > 360) - startAngle -= 360; - while (arcAngle > 360) - arcAngle -= 360; - while (arcAngle < -360) - arcAngle += 360; // negative arc angle is OK - // Check and set start and end angle - int endAngle = startAngle + arcAngle; - if (arcAngle >= 0) - { - if (endAngle > 360) // need 2 segments - { - drawTheArc(radius, style, fill, xscale, yscale, startAngle, 360, x0, y0); - drawTheArc(radius, style, fill, xscale, yscale, 0, endAngle - 360, x0, y0); - } else - drawTheArc(radius, style, fill, xscale, yscale, startAngle, endAngle, x0, y0); - } // else draw arc frem end to start - else if (endAngle < 0) // need 2 segments - { - drawTheArc(radius, style, fill, xscale, yscale, endAngle + 360, 360, x0, y0); - drawTheArc(radius, style, fill, xscale, yscale, 0, startAngle, x0, y0); - } else - drawTheArc(radius, style, fill, xscale, yscale, endAngle, startAngle, x0, y0); - - } - - private void drawTheCircle(int radius, int style, boolean fill, int xscale, - int yscale, int x0, int y0) - { - // Initialize scaled up Bresenham's circle algorithm - int f = (1 - ARC_ACC * radius); - int ddF_x = 0; - int ddF_y = -2 * ARC_ACC * radius; - int xc = 0; - int yc = ARC_ACC * radius; - int dotskip = 0; - while (xc < yc) - { - if (f >= 0) - { - yc--; - ddF_y += 2; - f += ddF_y; - } - - xc++; - ddF_x += 2; - f += ddF_x + 1; - - // Skip points for dotted version - dotskip = (dotskip + 1) % (2 * ARC_ACC); - if ((style == DOTTED) && !fill && (dotskip < ((2 * ARC_ACC) - 1))) - continue; - - // Scale down again - int xxp = (xc * xscale + (xscale >> 1)) / (ARC_ACC * ARC_ACC); - int xyp = (xc * yscale + (yscale >> 1)) / (ARC_ACC * ARC_ACC); - int yyp = (yc * yscale + (yscale >> 1)) / (ARC_ACC * ARC_ACC); - int yxp = (yc * xscale + (xscale >> 1)) / (ARC_ACC * ARC_ACC); - - if (fill) - { - /* TODO: Optimize more by drawing horizontal lines */ - drawLine(x0, y0, x0 + yxp, y0 - xyp, style); // 0 - 45 degrees - drawLine(x0, y0, x0 + xxp, y0 - yyp, style); // 45 - 90 degrees - drawLine(x0, y0, x0 - xxp, y0 - yyp, style); // 90 - 135 degrees - drawLine(x0, y0, x0 - yxp, y0 - xyp, style); // 135 - 180 degrees - drawLine(x0, y0, x0 - yxp, y0 + xyp, style); // 180 - 225 degrees - drawLine(x0, y0, x0 - xxp, y0 + yyp, style); // 225 - 270 degrees - drawLine(x0, y0, x0 + xxp, y0 + yyp, style); // 270 - 315 degrees - drawLine(x0, y0, x0 + yxp, y0 + xyp, style); // 315 - 360 degrees - } else - { - setPixel(x0 + yxp, y0 - xyp); // 0 - 45 degrees - setPixel(x0 + xxp, y0 - yyp); // 45 - 90 degrees - setPixel(x0 - xxp, y0 - yyp); // 90 - 135 degrees - setPixel(x0 - yxp, y0 - xyp); // 135 - 180 degrees - setPixel(x0 - yxp, y0 + xyp); // 180 - 225 degrees - setPixel(x0 - xxp, y0 + yyp); // 225 - 270 degrees - setPixel(x0 + xxp, y0 + yyp); // 270 - 315 degrees - setPixel(x0 + yxp, y0 + xyp); // 315 - 360 degrees - } - } - } - - private void drawTheArc(int radius, int style, boolean fill, int xscale, - int yscale, int startAngle, int endAngle, int x0, int y0) - { - // Initialize scaled up Bresenham's circle algorithm - int f = (1 - ARC_ACC * radius); - int ddF_x = 0; - int ddF_y = -2 * ARC_ACC * radius; - int xc = 0; - int yc = ARC_ACC * radius; - int dotskip = 0; - while (xc < yc) - { - if (f >= 0) - { - yc--; - ddF_y += 2; - f += ddF_y; - } - - xc++; - ddF_x += 2; - f += ddF_x + 1; - - // Skip points for dotted version - dotskip = (dotskip + 1) % (2 * ARC_ACC); - if ((style == DOTTED) && !fill && (dotskip < ((2 * ARC_ACC) - 1))) - continue; - - // Scale down again - int xxp = (xc * xscale + (xscale >> 1)) / (ARC_ACC * ARC_ACC); - int xyp = (xc * yscale + (yscale >> 1)) / (ARC_ACC * ARC_ACC); - int yyp = (yc * yscale + (yscale >> 1)) / (ARC_ACC * ARC_ACC); - int yxp = (yc * xscale + (xscale >> 1)) / (ARC_ACC * ARC_ACC); - - // Calculate angle for partly circles / ellipses - // NOTE: Below, (float) should not be needed. Not sure why Math.round() only accepts float. - int tp = (int) Math.round(Math.toDegrees(Math.atan2(yc, xc))); - if (fill) - { - /* TODO: Optimize more by drawing horizontal lines */ - if (((90 - tp) >= startAngle) && ((90 - tp) <= endAngle)) - drawLine(x0, y0, x0 + yxp, y0 - xyp, style); // 0 - 45 degrees - if ((tp >= startAngle) && (tp <= endAngle)) - drawLine(x0, y0, x0 + xxp, y0 - yyp, style); // 45 - 90 degrees - if (((180 - tp) >= startAngle) && ((180 - tp) <= endAngle)) - drawLine(x0, y0, x0 - xxp, y0 - yyp, style); // 90 - 135 degrees - if (((180 - (90 - tp)) >= startAngle) && ((180 - (90 - tp)) <= endAngle)) - drawLine(x0, y0, x0 - yxp, y0 - xyp, style); // 135 - 180 degrees - if (((270 - tp) >= startAngle) && ((270 - tp) <= endAngle)) - drawLine(x0, y0, x0 - yxp, y0 + xyp, style); // 180 - 225 degrees - if (((270 - (90 - tp)) >= startAngle) && ((270 - (90 - tp)) <= endAngle)) - drawLine(x0, y0, x0 - xxp, y0 + yyp, style); // 225 - 270 degrees - if (((360 - tp) >= startAngle) && ((360 - tp) <= endAngle)) - drawLine(x0, y0, x0 + xxp, y0 + yyp, style); // 270 - 315 degrees - if (((360 - (90 - tp)) >= startAngle) && ((360 - (90 - tp)) <= endAngle)) - drawLine(x0, y0, x0 + yxp, y0 + xyp, style); // 315 - 360 degrees - } else - { - if (((90 - tp) >= startAngle) && ((90 - tp) <= endAngle)) - setPixel(x0 + yxp, y0 - xyp); // 0 - 45 degrees - if ((tp >= startAngle) && (tp <= endAngle)) - setPixel(x0 + xxp, y0 - yyp); // 45 - 90 degrees - if (((180 - tp) >= startAngle) && ((180 - tp) <= endAngle)) - setPixel(x0 - xxp, y0 - yyp); // 90 - 135 degrees - if (((180 - (90 - tp)) >= startAngle) && ((180 - (90 - tp)) <= endAngle)) - setPixel(x0 - yxp, y0 - xyp); // 135 - 180 degrees - if (((270 - tp) >= startAngle) && ((270 - tp) <= endAngle)) - setPixel(x0 - yxp, y0 + xyp); // 180 - 225 degrees - if (((270 - (90 - tp)) >= startAngle) && ((270 - (90 - tp)) <= endAngle)) - setPixel(x0 - xxp, y0 + yyp); // 225 - 270 degrees - if (((360 - tp) >= startAngle) && ((360 - tp) <= endAngle)) - setPixel(x0 + xxp, y0 + yyp); // 270 - 315 degrees - if (((360 - (90 - tp)) >= startAngle) && ((360 - (90 - tp)) <= endAngle)) - setPixel(x0 + yxp, y0 + xyp); // 315 - 360 degrees - } - } - } - - /** - * Draw a rounded rectangle. - * @param x - * @param y - * @param width - * @param height - * @param arcWidth - * @param arcHeight - */ - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) - { - x += transX; - y += transY; - int xc = x + (width / 2); - int yc = y + (height / 2); - int a = arcWidth / 2; - int b = arcHeight / 2; - - int translateX = (width / 2) - (arcWidth / 2); - int translateY = (height / 2) - (arcHeight / 2); - - // Draw 4 sides: - int xDiff = arcWidth / 2; - int yDiff = arcHeight / 2; - drawLine(x, y + yDiff, x, y + height - yDiff); - drawLine(x + width, y + yDiff, x + width, y + height - yDiff); - drawLine(x + xDiff, y, x + width - xDiff, y); - drawLine(x + xDiff, y + height, x + width - xDiff, y + height); - - - /* e(x,y) = b^2*x^2 + a^2*y^2 - a^2*b^2 */ - int xxx = 0, yyy = b; - int a2 = a * a, b2 = b * b; - int crit1 = -(a2 / 4 + a % 2 + b2); - int crit2 = -(b2 / 4 + b % 2 + a2); - int crit3 = -(b2 / 4 + b % 2); - int t = -a2 * yyy; /* e(xxx+1/2,y-1/2) - (a^2+b^2)/4 */ - int dxt = 2 * b2 * xxx, dyt = -2 * a2 * yyy; - int d2xt = 2 * b2, d2yt = 2 * a2; - - while (yyy >= 0 && xxx <= a) - { - setPixel(xc + xxx + translateX, yc + yyy + translateY); // Q4 - if (xxx != 0 || yyy != 0) - setPixel(xc - xxx - translateX, yc - yyy - translateY); // Q2 - if (xxx != 0 && yyy != 0) - { - setPixel(xc + xxx + translateX, yc - yyy - translateY); // Q1 - setPixel(xc - xxx - translateX, yc + yyy + translateY); // Q3 - } - if (t + b2 * xxx <= crit1 - || /* e(xxx+1,y-1/2) <= 0 */ t + a2 * yyy <= crit3) /* e(xxx+1/2,y) <= 0 */ - - { - xxx++; - dxt += d2xt; - t += dxt; - } // incx() - else if (t - a2 * yyy > crit2) /* e(xxx+1/2,y-1) > 0 */ - - { - yyy--; - dyt += d2yt; - t += dyt; - } else - { - { - xxx++; - dxt += d2xt; - t += dxt; - } // incx() - { - yyy--; - dyt += d2yt; - t += dyt; - } - } - } - } - - /** - * Draw a rectangle using the current color and style. - * @param x - * @param y - * @param width - * @param height - */ - public void drawRect(int x, int y, int width, int height) - { - x += transX; - y += transY; - if ((width < 0) || (height < 0)) - return; - - if (height == 0 || width == 0) - { - drawLine(x, y, x + width, y + height); - } else - { - drawLine(x, y, x + width - 1, y); - drawLine(x + width, y, x + width, y + height - 1); - drawLine(x + width, y + height, x + 1, y + height); - drawLine(x, y + height, x, y + 1); - } - } - - /** - * Draw a filled rectangle using the current color. - * @param x - * @param y - * @param w - * @param h - */ - public void fillRect(int x, int y, int w, int h) - { - x += transX; - y += transY; - if ((w < 0) || (h < 0)) - return; - bitBlt(imageBuf, width, height, x, y, imageBuf, width, height, x, y, w, h, (rgbColor == BLACK ? ROP_SET : ROP_CLEAR)); - } - - /** - * Return the current stroke style. - * @return current style. - */ - public int getStrokeStyle() - { - return strokeStyle; - } - - /** - * Set the stroke style to be used for drawing operations. - * @param style new style. - */ - public void setStrokeStyle(int style) - { - if (style != SOLID && style != DOTTED) - { - throw new IllegalArgumentException(); - } - strokeStyle = style; - } - - /** - * Copy one rectangular area of the drawing surface to another. - * @param sx Source x - * @param sy Source y - * @param w Source width - * @param h Source height - * @param x Destination x - * @param y Destination y - * @param anchor location of the anchor point of the destination. - */ - 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); - bitBlt(imageBuf, width, height, sx, sy, imageBuf, width, height, x, y, w, h, ROP_COPY); - } - - /** - * Translates the origin of the graphics context to the point - * (x, y) in the current coordinate system. Calls are cumulative. - * - * @param x the new translation origin x value - * @param y new translation origin y value - * @see #getTranslateX() - * @see #getTranslateY() - */ - public synchronized void translate(int x, int y) - { - transX += x; - transY += y; - } - - /** - * Gets the X coordinate of the translated origin of this graphics context. - * @return X of current origin - */ - public synchronized int getTranslateX() - { - return transX; - } - - /** - * Gets the Y coordinate of the translated origin of this graphics context. - * @return Y of current origin - */ - public synchronized int getTranslateY() - { - return transY; - } -} - diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3I2CPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3I2CPort.java deleted file mode 100644 index 095bfd2..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3I2CPort.java +++ /dev/null @@ -1,154 +0,0 @@ -package lejos.internal.ev3; - -import java.io.IOError; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import lejos.hardware.port.I2CException; -import lejos.hardware.port.I2CPort; -import lejos.internal.io.NativeDevice; -import lejos.utility.Delay; - -/** - Provide access to EV3 I2C sensors.
    - NOTE: The EV3 iic kernel module provides the capability to make an i2c sensor - have a similar interface to that used for uart based sensors. In particular it - provides a mechanism to have the kernel poll the sensor. However this mode seems - to be of limited use because most i2c sensors provide multiple data values etc. - Because of this we only implement the basic i2c interface. - */ -public class EV3I2CPort extends EV3IOPort implements I2CPort -{ - protected static NativeDevice i2c; - static { - initDeviceIO(); - } - protected static final int IIC_CONNECT = 0xc0036907; - protected static final int IIC_DISCONNECT = 0xc0036908; - protected static final int IIC_IO = 0xc0036909; - - protected static final int IO_TIMEOUT = 2000; - - protected static final byte SPEED_10KHZ = 0; - protected static final byte SPEED_100KHZ = 1; - - - /** Maximum read/write request length */ - public static final int MAX_IO = IIC_DATA_LENGTH; - - protected byte[] cmd = new byte[IIC_DATA_LENGTH + 5]; - protected byte speed = SPEED_10KHZ; - - protected boolean initSensor() - { - cmd[0] = (byte)port; - i2c.ioctl(IIC_CONNECT, cmd); - return true; - } - - /** - * allow access to the specified port - * @param p port number to open - */ - public boolean open(int t, int p, EV3Port r) - { - if (!super.open(t, p, r)) - return false; - // Set pin state to a sane default - setPinMode(CMD_FLOAT); - return true; - } - - /** {@inheritDoc} - */ - @Override - public void close() - { - cmd[0] = (byte)port; - i2c.ioctl(IIC_DISCONNECT, cmd); - super.close(); - } - - - @Override - public boolean setType(int type) - { - //System.out.println("Set type " + type); - speed = SPEED_10KHZ; - switch(type) - { - case TYPE_HIGHSPEED: - speed = SPEED_100KHZ; - // fall through - case TYPE_LOWSPEED: - setPinMode(CMD_SET|CMD_PIN5); - break; - case TYPE_HIGHSPEED_9V: - speed = SPEED_100KHZ; - // fall through - case TYPE_LOWSPEED_9V: - setPinMode(CMD_SET|CMD_PIN1|CMD_PIN5); - break; - default: - return false; - } - return initSensor(); - } - - - /** - * High level i2c interface. Perform a complete i2c transaction and return - * the results. Writes the specified data to the device and then reads the - * requested bytes from it. - * @param deviceAddress The I2C device address. - * @param writeBuf The buffer containing data to be written to the device. - * @param writeOffset The offset of the data within the write buffer - * @param writeLen The number of bytes to write. - * @param readBuf The buffer to use for the transaction results - * @param readOffset Location to write the results to - * @param readLen The length of the read - */ - public synchronized void i2cTransaction(int deviceAddress, byte[]writeBuf, - int writeOffset, int writeLen, byte[] readBuf, int readOffset, - int readLen) - { - //long st = System.currentTimeMillis(); - cmd[0] = (byte)port; - cmd[1] = speed; - cmd[2] = (byte) readLen; - cmd[3] = (byte) writeLen; - cmd[4] = (byte) (deviceAddress >> 1); - if (writeLen > 0) System.arraycopy(writeBuf, writeOffset, cmd, 5, writeLen); - i2c.ioctl(IIC_IO, cmd); - int result = (int) cmd[1]; - if (result == STATUS_FAIL) - throw new I2CException("I2C I/O error"); - if (result == STATUS_BUSY) - throw new I2CException("I2C Bus busy"); - if (result == STATUS_OK) - { - //System.out.println("iic time " + (System.currentTimeMillis() - st)); - if (readLen > 0) - System.arraycopy(cmd, 5, readBuf, readOffset, readLen); - return; - } - //System.out.println("i2c error res is " + result); - throw new I2CException("I2C Unexpected error " + result); - } - - - private static void initDeviceIO() - { - try { - i2c = new NativeDevice("/dev/lms_iic"); - } catch (IOError e) - { - throw new UnsupportedOperationException("Unable to access EV3 hardware. Is this an EV3?", e); - } - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3IOPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3IOPort.java deleted file mode 100644 index 144fbdf..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3IOPort.java +++ /dev/null @@ -1,143 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.port.BasicSensorPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * This class provides the base operations for local EV3 sensor ports. - * @author andy - * - */ -public abstract class EV3IOPort implements IOPort, BasicSensorPort, EV3SensorConstants -{ - protected int port = -1; - protected int typ = -1; - protected EV3Port ref; - protected int currentMode = 0; - protected static EV3IOPort [][] openPorts = new EV3IOPort[EV3Port.MOTOR_PORT+1][PORTS]; - - - /** {@inheritDoc} - */ - @Override - public String getName() - { - return ref.getName(); - } - - /** {@inheritDoc} - */ - @Override - public int getMode() - { - return currentMode; - } - - /** {@inheritDoc} - */ - @Override - public int getType() - { - return 0; - } - - /** {@inheritDoc} - */ - @Override - public boolean setMode(int mode) - { - currentMode = mode; - return true; - } - - /** {@inheritDoc} - */ - @Override - public boolean setType(int type) - { - throw new UnsupportedOperationException("This operation is not supported by this sensor"); - - } - - /** {@inheritDoc} - */ - @Override - public boolean setTypeAndMode(int type, int mode) - { - setType(type); - setMode(mode); - return true; - } - - /** - * Open the sensor port. Ensure that the port is only opened once. - * @param typ The type of port motor/sensor - * @param port the port number - * @param ref the Port ref for this port - * @return - */ - public boolean open(int typ, int port, EV3Port ref) - { - synchronized (openPorts) - { - if (openPorts[typ][port] == null) - { - // Set into connected state and disable auto detection - this.port = port; - this.typ = typ; - if (!setPinMode(CMD_CONNECTED)) - { - this.port = -1; - return false; - } - openPorts[typ][port] = this; - this.ref = ref; - if (typ == EV3Port.SENSOR_PORT) - { - // set sane pin states, automatic detection may have changed them. - setPinMode(CMD_FLOAT); - } - return true; - } - return false; - } - } - - /** {@inheritDoc} - */ - @Override - public void close() - { - if (port == -1) - return; - synchronized (openPorts) - { - setPinMode(CMD_DISCONNECTED); - openPorts[typ][port] = null; - port = -1; - } - } - - /** - * Set the port pins up ready for use. - * @param mode The EV3 pin mode - */ - public boolean setPinMode(int mode) - { - //System.out.println("Set Pin mode port " + port + " value " + mode); - return EV3ConfigurationPort.setPortMode(typ, port, mode); - } - - /** - * Close all open ports - */ - public static void closeAll() - { - for(int typ = 0; typ < openPorts.length; typ++) - for(int prt = 0; prt < openPorts[typ].length; prt++) - if (openPorts[typ][prt] != null) - openPorts[typ][prt].close(); - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Key.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Key.java deleted file mode 100644 index 531fea8..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Key.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.internal.ev3; - -import java.util.ArrayList; - -import lejos.hardware.Key; -import lejos.hardware.KeyListener; -import lejos.utility.Delay; - -public class EV3Key implements Key { - private static final int WAITFOR_RELEASE_SHIFT = 8; - private static final int DEBOUNCE_TIME = 10; - private static final int KEY_PRESS_TIME = 100; - - private int iCode; - private EV3Keys keys; - - private static String[] keyNames = {"Up", "Enter", "Down", "Right", "Left", "Escape"}; - private String name; - - private ArrayList listeners; - - public EV3Key(EV3Keys keys, String name) { - this.iCode = getKeyId(name); - this.keys = keys; - this.name = name; - } - - @Override - public int getId() { - return iCode; - } - - @Override - public boolean isDown() { - return (keys.readButtons() & iCode) != 0; - } - - @Override - public boolean isUp() { - return (keys.readButtons() & iCode) == 0; - } - - @Override - public void waitForPress() { - while ((keys.waitForAnyPress(0) & iCode) == 0) - { - // wait for next press - } - } - - @Override - public void waitForPressAndRelease() { - this.waitForPress(); - int tmp = iCode << WAITFOR_RELEASE_SHIFT; - while ((keys.waitForAnyEvent(0) & tmp) == 0) - { - // wait for next event - } - } - - @Override - public void addKeyListener(KeyListener listener) { - if (listeners == null) { - listeners = new ArrayList(); - } - listeners.add(listener); - keys.addListener(iCode, this); - } - - @Override - public void simulateEvent(int event) { - int simulatedState = keys.getSimulatedState(); - if (event == Key.KEY_PRESSED) keys.setSimultedState(simulatedState |= iCode); // set bit - else if (event == Key.KEY_RELEASED) keys.setSimultedState(simulatedState &= ~iCode); // unset bit - else if (event == Key.KEY_PRESSED_AND_RELEASED) { - keys.setSimultedState(simulatedState |= iCode); - Delay.msDelay(KEY_PRESS_TIME); - keys.setSimultedState(simulatedState &= ~iCode); - } - } - - public void callListeners() { - boolean pressed = isDown(); - - if (listeners != null) - for(KeyListener listener: listeners) { - if (pressed) listener.keyPressed(this); - else listener.keyReleased(this); - } - } - - public static int getKeyPos(String name) { - for(int i=0;i listeners; - - private static final int DEBOUNCE_TIME = 10; - private static final int POLL_TIME = 50; - - private static int simulatedState; - - // protected by monitor - private int clickVol; - private int clickLen; - private int clickFreq = 1000; - private int curButtonsS; - // not protected by any monitor - private int curButtonsE; - - private NativeDevice dev; - private ByteBuffer buttonState; - - public EV3Keys() { - clickVol = SystemSettings.getIntSetting(VOL_SETTING, 20); - clickLen = SystemSettings.getIntSetting(LEN_SETTING, 50); - clickFreq = SystemSettings.getIntSetting(FREQ_SETTING, 1000); - dev = new NativeDevice("/dev/lms_ui"); - buttonState = dev.mmap(6).getByteBuffer(0, 6); - curButtonsE = curButtonsS = getButtons(); - } - - @Override - public void discardEvents() { - curButtonsE = getButtons(); - } - - @Override - public int waitForAnyEvent() { - return waitForAnyEvent(0); - } - - @Override - public int waitForAnyEvent(int timeout) { - long end = (timeout == 0 ? 0x7fffffffffffffffL : System - .currentTimeMillis() + timeout); - try { - int oldDown = curButtonsE; - while (true) { - long curTime = System.currentTimeMillis(); - if (curTime >= end) - return 0; - Thread.sleep(POLL_TIME); - int newDown = curButtonsE = readButtons(); - if (newDown != oldDown) - { - Thread.sleep(POLL_TIME); - newDown |= readButtons(); - curButtonsE = newDown; - return ((oldDown & (~newDown)) << WAITFOR_RELEASE_SHIFT) - | (newDown & (~oldDown)); - } - } - } catch (InterruptedException e) { - // TODO: Need to decide how to handle this properly - // preserve state of interrupt flag - Thread.currentThread().interrupt(); - return 0; - } finally { - } - } - - @Override - public int waitForAnyPress(int timeout) { - long end = (timeout == 0 ? 0x7fffffffffffffffL : System - .currentTimeMillis() + timeout); - try { - int oldDown = curButtonsE; - while (true) { - long curTime = System.currentTimeMillis(); - if (curTime >= end) - return 0; - Thread.sleep(POLL_TIME); - int newDown = curButtonsE = readButtons(); - int pressed = newDown & (~oldDown); - if (pressed != 0) - return pressed; - - oldDown = newDown; - } - } catch (InterruptedException e) { - // TODO: Need to decide how to handle this properly - // preserve state of interrupt flag - Thread.currentThread().interrupt(); - return 0; - } finally { - } - } - - @Override - public int waitForAnyPress() { - return waitForAnyPress(0); - } - - @Override - public int getButtons() { - // read buttons and de-bounce them - int state1, state2 = 0; - for (;;) { - state1 = checkButtons(); - if (state1 == state2) - return state1 | simulatedState; - Delay.msDelay(DEBOUNCE_TIME); - state2 = checkButtons(); - } - } - - @Override - public int readButtons() { - int newButtons = getButtons(); - int pressed = newButtons & (~curButtonsS); - curButtonsS = newButtons; - if (pressed != 0 && clickVol != 0) { - int tone = clickFreq; - if (tone != 0) - Sound.playTone(tone, clickLen, -clickVol); - } - return newButtons; - } - - @Override - public void setKeyClickVolume(int vol) { - clickVol = vol; - } - - @Override - public int getKeyClickVolume() { - return clickVol; - } - - @Override - public void setKeyClickLength(int len) { - clickLen = len; - } - - @Override - public int getKeyClickLength() { - return clickLen; - } - - @Override - public void setKeyClickTone(int key, int freq) { - clickFreq = freq; - } - - @Override - public int getKeyClickTone(int key) { - return clickFreq; - } - - private int checkButtons() { - int state = 0; - for (int i = 0; i < buttonState.capacity(); i++) - if (buttonState.get(i) != 0) - state |= 1 << i; - return state; - } - - public void setSimultedState(int state) { - simulatedState = state; - } - - public int getSimulatedState() { - return simulatedState; - } - - void addListener(int iCode,EV3Key key) { - if (listeners == null) { - listeners = new HashMap(); - new KeysListenThread().start(); - } - listeners.put(iCode, key); - } - - class KeysListenThread extends Thread { - - public KeysListenThread() { - setDaemon(true); - } - - @Override - public void run() { - while (true) { - int state = EV3Keys.this.waitForAnyEvent(); - - int mask = 1; - for (int i=0;i 0) - Delay.msDelay(waitTime); - } - - /** - * Refresh the display. If auto refresh is off, this method will wait until - * the display refresh has completed. If auto refresh is on it will return - * immediately. - */ - public void refresh() - { - layer.refresh(); - } - - /** - * Clear the display. - */ - public void clear() - { - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ROP_CLEAR); - } - - /** - * Provide access to the LCD display frame buffer. Allows both the firmware - * and Java to make changes. - * @return byte array that is the frame buffer. - */ - public byte[] getDisplay() - { - return displayBuf; - } - - /** - * Set the period used to perform automatic refreshing of the display. - * A period of 0 disables the refresh. - * @param period time in ms - * @return the previous refresh period. - */ - public int setAutoRefreshPeriod(int period) - { - return 0; - } - - /** - * Turn on/off the automatic refresh of the LCD display. At system startup - * auto refresh is on. - * @param on true to enable, false to disable - */ - public void setAutoRefresh(boolean on) - { - layer.setAutoRefresh(on); - } - - /** - * Method to set a pixel on the screen. - * @param x the x coordinate - * @param y the y coordinate - * @param color the pixel color (0 = white, 1 = black) - */ - public void setPixel(int x, int y, int color) - { - bitBlt(displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, x, y, 1, 1,(color == 1 ? ROP_SET : ROP_CLEAR)); - } - - /** - * Method to get a pixel from the screen. - * @param x the x coordinate - * @param y the y coordinate - * @return the pixel color (0 = white, 1 = black) - */ - public int getPixel(int x, int y) { - if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) return 0; - int bit = (x & 0x7); - //int index = (y)*SCREEN_WIDTH + x; - int index = (y)*SCREEN_MEM_WIDTH + x/8; - return ((displayBuf[index] >> bit) & 1); - } - - /** - * Standard two input BitBlt function. Supports standard raster ops and - * overlapping images. Images are held in native leJOS/Lego format. - * @param src byte array containing the source image - * @param sw Width of the source image - * @param sh Height of the source image - * @param sx X position to start the copy from - * @param sy Y Position to start the copy from - * @param dst byte array containing the destination image - * @param dw Width of the destination image - * @param dh Height of the destination image - * @param dx X destination - * @param dy Y destination - * @param w width of the area to copy - * @param h height of the area to copy - * @param rop raster operation. - */ - 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) - { - /* This is a partial implementation of the BitBlt algorithm. It provides a - * complete set of raster operations and handles partial and fully aligned - * images correctly. Overlapping source and destination images is also - * supported. It does not performing mirroring. The code was converted - * from an initial Java implementation and has not been optimized for C. - * The general mechanism is to perform the block copy with Y as the inner - * loop (because on the display the bits are packed y-wise into a byte). We - * perform the various rop cases by reducing the operation to a series of - * AND and XOR operations. Each step is controlled by a byte in the rop code. - * This mechanism is based upon that used in the X Windows system server. - */ - // Clip to source and destination - int trim; - if (dx < 0) - { - trim = -dx; - dx = 0; - sx += trim; - w -= trim; - } - if (dy < 0) - { - trim = -dy; - dy = 0; - sy += trim; - h -= trim; - } - if (sx < 0 || sy < 0) return; - if (dx + w > dw) w = dw - dx; - if (sx + w > sw) w = sw - sx; - if (w <= 0) return; - if (dy + h > dh) h = dh - dy; - if (sy + h > sh) h = sh - sy; - if (h <= 0) return; - // Setup initial parameters and check for overlapping copy - int xinc = 1; - int yinc = 1; - byte firstBit = 1; - if (src == dst) - { - // If copy overlaps we use reverse direction - if (dy > sy) - { - sy = sy + h - 1; - dy = dy + h - 1; - yinc = -1; - } - if (dx > sx) - { - firstBit = (byte)0x80; - xinc = -1; - sx = sx + w - 1; - dx = dx + w - 1; - } - } - if (src == null) - src = dst; - int swb = (sw+7)/8; - int dwb = (dw+7)/8; - //if (src == displayBuf) - //swb = HW_MEM_WIDTH; - //if (dst == displayBuf) - //dwb = HW_MEM_WIDTH; - int inStart = sy*swb; - int outStart = dy*dwb; - byte inStartBit = (byte)(1 << (sx & 0x7)); - byte outStartBit = (byte)(1 << (dx & 0x7)); - dwb *= yinc; - swb *= yinc; - // Extract rop sub-fields - byte ca1 = (byte)(rop >> 24); - byte cx1 = (byte)(rop >> 16); - byte ca2 = (byte)(rop >> 8); - byte cx2 = (byte) rop; - boolean noDst = (ca1 == 0 && cx1 == 0); - int ycnt; - // Check for byte aligned case and optimise for it - if (w >= 8 && inStartBit == firstBit && outStartBit == firstBit) - { - int ix = sx/8; - int ox = dx/8; - int byteCnt = w/8; - ycnt = h; - while (ycnt-- > 0) - { - int inIndex = inStart + ix; - int outIndex = outStart + ox; - int cnt = byteCnt; - while(cnt-- > 0) - { - if (noDst) - dst[outIndex] = (byte)((src[inIndex] & ca2)^cx2); - else - { - byte inVal = src[inIndex]; - dst[outIndex] = (byte)((dst[outIndex] & ((inVal & ca1)^cx1)) ^ ((inVal & ca2)^cx2)); - } - outIndex += xinc; - inIndex += xinc; - } - ix += swb; - ox += dwb; - } - // Do we have a final non byte multiple to do? - w &= 0x7; - if (w == 0) - { - //if (dst == displayBuf) - //update(displayBuf); - return; - } - //inStart = sy*swb; - //outStart = dy*dwb; - sx += byteCnt*8; - dx += byteCnt*8; - } - // General non byte aligned case - int ix = sx/8; - int ox = dx/8; - ycnt = h; - while(ycnt-- > 0) - { - int inIndex = inStart + ix; - byte inBit = inStartBit; - byte inVal = src[inIndex]; - byte inAnd = (byte)((inVal & ca1)^cx1); - byte inXor = (byte)((inVal & ca2)^cx2); - int outIndex = outStart + ox; - byte outBit = outStartBit; - byte outPixels = dst[outIndex]; - int cnt = w; - while(true) - { - if (noDst) - { - if ((inXor & inBit) != 0) - outPixels |= outBit; - else - outPixels &= ~outBit; - } - else - { - byte resBit = (byte)((outPixels & ((inAnd & inBit) != 0 ? outBit : 0))^((inXor & inBit) != 0 ? outBit : 0)); - outPixels = (byte)((outPixels & ~outBit) | resBit); - } - if (--cnt <= 0) break; - if (xinc > 0) - { - inBit <<= 1; - outBit <<= 1; - } - else - { - inBit >>= 1; - outBit >>= 1; - } - if (inBit == 0) - { - inBit = firstBit; - inIndex += xinc; - inVal = src[inIndex]; - inAnd = (byte)((inVal & ca1)^cx1); - inXor = (byte)((inVal & ca2)^cx2); - } - if (outBit == 0) - { - dst[outIndex] = outPixels; - outBit = firstBit; - outIndex += xinc; - outPixels = dst[outIndex]; - } - } - dst[outIndex] = outPixels; - inStart += swb; - outStart += dwb; - } - //if (dst == displayBuf) - //update(displayBuf); - } - - /** - * Set the LCD contrast. - * @param contrast 0 blank 0x60 full on - */ - public void setContrast(int contrast) - { - // Not implemented - } - - public byte[] getHWDisplay() { - return lcdMan.getHWDisplay(); - } - - @Override - public int getWidth() { - return SCREEN_WIDTH; - } - - @Override - public int getHeight() { - return SCREEN_HEIGHT; - } -} - diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3LCDManager.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3LCDManager.java deleted file mode 100644 index 00a2b50..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3LCDManager.java +++ /dev/null @@ -1,330 +0,0 @@ -package lejos.internal.ev3; - -import java.io.Closeable; -import java.util.ArrayList; - -import lejos.internal.io.NativeDevice; -import lejos.utility.Delay; - -import com.sun.jna.Pointer; - -/** - * This class provides management of a set of LCD layers.
    - * Each layer can be used as the frame buffer for text/graphics output. Layers can be - * made visible or invisible. If more than one layer is visible the layers will be - * combined and will overlay each other on the display. Layers are named and this - * name can be used to access the layer. - * @author andy - * - */ -public class EV3LCDManager -{ - public static final int DEFAULT_REFRESH_PERIOD = 250; - protected final static int HW_MEM_WIDTH = ((EV3LCD.SCREEN_WIDTH + 31)/32)*4; // width of HW Buffer in bytes - protected final static int LCD_HW_BUFFER_LENGTH = HW_MEM_WIDTH*EV3LCD.SCREEN_HEIGHT; - protected NativeDevice dev = new NativeDevice("/dev/fb0"); - protected Pointer lcd = dev.mmap(LCD_HW_BUFFER_LENGTH); - protected boolean autoRefresh = true; - protected long refreshTime = 0; - - protected byte [] hwBuffer = new byte[LCD_HW_BUFFER_LENGTH]; - private static LCDUpdate updateThread; - protected static EV3LCDManager localLCDManager = new EV3LCDManager(); - protected ArrayList layers = new ArrayList(); - protected volatile LCDLayer [] visibleLayers = new LCDLayer[0]; - static - { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() {localLCDManager.closeAll();} - }); - } - - /** - * The actual layer object. provides a basic container for the frame buffer. - * @author andy - * - */ - static public class LCDLayer implements Closeable - { - protected byte [] displayBuf = null; - protected boolean visible = false; - protected boolean autoRefresh = true; - protected String name; - protected int openCnt = 0; - - /** - * Create the layer and give it a name - * @param name the name of the layer - */ - public LCDLayer(String name) - { - this.name = name; - } - - /** - * Open the layer making it available for use - */ - public synchronized void open() - { - if (openCnt++ == 0) - { - displayBuf = new byte[EV3LCD.LCD_BUFFER_LENGTH]; - setVisible(true); - } - } - - /** - * Close the layer, closed layers can not be written to. - */ - @Override - public synchronized void close() - { - if (openCnt <= 0) - throw new IllegalStateException("layer is not open"); - if (openCnt == 1) - { - setVisible(false); - displayBuf = null; - } - openCnt--; - } - - /** - * Check to see if the layer is open - * @return - */ - public synchronized boolean isOpen() - { - return openCnt > 0; - } - - /** - * Set the visibility of the layer. Note that invisible layers can still be updated. - * @param visible true to make the layer visible, false to hide it - */ - public void setVisible(boolean visible) - { - if (openCnt > 0) - { - this.visible = visible; - localLCDManager.buildVisibleList(); - } - } - - /** - * Enable/disable automatic refresh for the layer. - * @param refresh turn auto refresh on/off - */ - public void setAutoRefresh(boolean refresh) - { - this.autoRefresh = refresh; - localLCDManager.buildVisibleList(); - } - - /** - * return the name of the layer - * @return the layer name - */ - public String getName() - { - return name; - } - - /** - * Get the frame buffer - * @return the array of bytes that represents the frame buffer for this layer - */ - public byte[] getDisplay() - { - return displayBuf; - } - - /** - * Update the hardware display. - */ - public void refresh() - { - localLCDManager.update(); - } - - } - - /** - * Iternal class to manage the hardware update - * @author andy - * - */ - class LCDUpdate extends Thread { - - public LCDUpdate() - { - setDaemon(true); - } - /** - * Background thread which provides automatic screen updates - */ - public void run() - { - for(;;) - { - long now = System.currentTimeMillis(); - if (now >= refreshTime) - { - if (autoRefresh) - update(); - else - refreshTime = now + DEFAULT_REFRESH_PERIOD; - } - Delay.msDelay(refreshTime - now); - } - } - } - - - private EV3LCDManager() { - if (updateThread == null) { - updateThread = new LCDUpdate(); - updateThread.start(); - } - } - - /** - * return the LCD manager object - * @return the manager - */ - public static EV3LCDManager getLocalLCDManager() - { - return localLCDManager; - } - - /** - * Helper function locate the named layer. - * @param name - * @return - */ - protected LCDLayer findLayer(String name) - { - for(LCDLayer l : layers) - if (l.getName().equals(name)) - return l; - return null; - } - - /** - * Return the requested layer. - * @param name the name of the layer to be located - * @return The layer - */ - public synchronized LCDLayer getLayer(String name) - { - LCDLayer l = findLayer(name); - if (l == null) - throw new IllegalArgumentException("Layer does not exist " + name); - return l; - } - - /** - * return an array containing all of the current layers - * @return array of layers - */ - public LCDLayer[] getLayers() - { - return layers.toArray(new LCDLayer[layers.size()]); - } - - /** - * Create a new layer with the provided name. - * @param name the layer name - * @return the layer - */ - public synchronized LCDLayer newLayer(String name) - { - if (findLayer(name) != null) - throw new IllegalArgumentException("Layer already exists " + name); - LCDLayer l = new LCDLayer(name); - layers.add(l); - return l; - } - - /** - * Helper function. Build a list of layers that should be displayed. - */ - protected synchronized void buildVisibleList() - { - // count how many layers are visible - int visCnt = 0; - for(LCDLayer l : layers) - if (l.visible && l.displayBuf != null) - visCnt++; - LCDLayer [] vis = new LCDLayer[visCnt]; - // place layers into list - visCnt = 0; - autoRefresh = false; - for(LCDLayer l : layers) - if (l.visible && l.displayBuf != null) - { - vis[visCnt++] = l; - autoRefresh |= l.autoRefresh; - } - // Make the new list active - visibleLayers = vis; - update(); - } - - /** - * Helper method. Copy all of the visible layers to the HW screen - */ - synchronized protected void update() - { - LCDLayer[] vis = visibleLayers; - if (vis.length > 0) - { - // copy first layer to the display - for(int row = 0; row < EV3LCD.SCREEN_HEIGHT; row++) - System.arraycopy(vis[0].displayBuf, row*EV3LCD.SCREEN_MEM_WIDTH, hwBuffer, row*HW_MEM_WIDTH, EV3LCD.SCREEN_MEM_WIDTH); - // now or in any other layers - for(int i = 1; i < vis.length; i++) - for(int row = 0; row < EV3LCD.SCREEN_HEIGHT; row++) - for(int col = 0; col < EV3LCD.SCREEN_MEM_WIDTH; col++) - hwBuffer[row*HW_MEM_WIDTH + col] |= vis[i].displayBuf[row*EV3LCD.SCREEN_MEM_WIDTH + col]; - lcd.write(0, hwBuffer, 0, hwBuffer.length); - } - else - { - // nothing to display, clear the screen - for(int i = 0; i < hwBuffer.length; i++) - hwBuffer[i] = 0; - } - lcd.write(0, hwBuffer, 0, hwBuffer.length); - refreshTime = System.currentTimeMillis() + DEFAULT_REFRESH_PERIOD; - } - - /** - * Close all open layers. - */ - protected void closeAll() - { - for(LCDLayer l : layers) - while (l.isOpen()) - l.close(); - } - - /** - * Return the contents of the hardware display. - * @return - */ - public byte[] getHWDisplay() - { - byte[] buffer = new byte[EV3LCD.LCD_BUFFER_LENGTH]; - byte [] hwBuffer = new byte[LCD_HW_BUFFER_LENGTH]; - - lcd.read(0, hwBuffer, 0, LCD_HW_BUFFER_LENGTH); - - for(int row = 0; row < EV3LCD.SCREEN_HEIGHT; row++) - { - System.arraycopy(hwBuffer, row*HW_MEM_WIDTH, buffer, row*EV3LCD.SCREEN_MEM_WIDTH, EV3LCD.SCREEN_MEM_WIDTH); - } - return buffer; - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3LED.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3LED.java deleted file mode 100644 index 0661d5e..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3LED.java +++ /dev/null @@ -1,33 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.LED; -import lejos.internal.io.NativeDevice; - -public class EV3LED implements LED { - private static NativeDevice dev = new NativeDevice("/dev/lms_ui"); - public static int COLOR_NONE = 0; - public static int COLOR_GREEN = 1; - public static int COLOR_RED = 2; - public static int COLOR_ORANGE = 3; - public static int PATTERN_ON = 0; - public static int PATTERN_BLINK = 1; - public static int PATTERN_HEARTBEAT = 2; - - - @Override - public void setPattern(int pattern) { - byte [] cmd = new byte[2]; - - cmd[0] = (byte)('0' + pattern); - dev.write(cmd, cmd.length); - } - - public void setPattern(int color, int pattern) { - if (color == 0 ) { - setPattern(0); - } - else { - setPattern(pattern * 3 + color); - } - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3MotorPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3MotorPort.java deleted file mode 100644 index 076ebb6..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3MotorPort.java +++ /dev/null @@ -1,825 +0,0 @@ -package lejos.internal.ev3; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; - -import lejos.hardware.motor.MotorRegulator; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.TachoMotorPort; -import lejos.internal.io.NativeDevice; -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; -import lejos.utility.Delay; - -/** - * Abstraction for an EV3 output port. - * - * TODO: Sort out a better way to do this, or least clean up the magic numbers. - * - */ -public class EV3MotorPort extends EV3IOPort implements TachoMotorPort { - static final byte OUTPUT_CONNECT = (byte)1; - static final byte OUTPUT_DISCONNECT = (byte)2; - static final byte OUTPUT_START = (byte)4; - static final byte OUTPUT_STOP = (byte)5; - static final byte OUTPUT_SET_TYPE = (byte)6; - static final byte OUTPUT_CLR_COUNT = (byte)7; - static final byte OUTPUT_POWER = (byte)8; - - - protected static byte[] regCmd2 = new byte[55*4]; - protected static NativeDevice tacho; - protected static ByteBuffer bbuf; - protected static IntBuffer ibuf; - protected static IntBuffer ibufShadow; - protected static NativeDevice pwm; - static - { - initDeviceIO(); - } - protected int curMode = FLOAT+1; // current mode is unknown - protected byte[] cmd = new byte[3]; - protected MotorRegulator regulator; - protected static final EV3MotorRegulatorKernelModule[] syncSlave = new EV3MotorRegulatorKernelModule[0]; - - /** - * Implementation of a PID based motor regulator that uses a kernel module - * for the core regulation operations. This mechanism is accessed via the - * EV3MotorPort class. - **/ - public class EV3MotorRegulatorKernelModule extends Thread implements MotorRegulator - { - static final int NO_LIMIT = 0x7fffffff; - // Regulator move states - static final int ST_IDLE = 0; - static final int ST_STALL = 1; - static final int ST_HOLD = 2; - static final int ST_START = 3; - static final int ST_ACCEL = 4; - static final int ST_MOVE = 5; - static final int ST_DECEL = 6; - - protected final int port; - protected int zeroTachoCnt; - protected int limitAngle; - protected float curPosition; - protected float curVelocity; - protected float curCnt; - protected int curTime; - protected int curState; - protected int curSerial; - protected int curLimit; - protected int curTachoCnt; - protected float curSpeed; - protected float curAcc; - protected boolean curHold; - protected boolean newMove; - protected int stallLimit=50; - protected int stallTime=1000; - protected EV3MotorRegulatorKernelModule[] syncThis = new EV3MotorRegulatorKernelModule[] {this}; - protected EV3MotorRegulatorKernelModule[] syncWith = syncThis; - protected EV3MotorRegulatorKernelModule[] syncActive = syncThis; - - protected byte[] regCmd = new byte[55]; - - // state for listener stuff - boolean started = false; - RegulatedMotorListener listener; - RegulatedMotor motor; - - public EV3MotorRegulatorKernelModule(TachoMotorPort p) - { - if (p != EV3MotorPort.this) - throw new IllegalArgumentException("Invlaid port specified"); - // don't wait for the listener thread to finish - this.setDaemon(true); - // cache the actual port number - this.port = EV3MotorPort.this.port; - } - - // Fixed point routines and constants - static final int FIX_SCALE = 256; - - protected int floatToFix(float f) - { - return Math.round(f*FIX_SCALE); - } - - protected int intToFix(int i) - { - return i*FIX_SCALE; - } - - protected float FixToFloat(int fix) - { - return (float)fix/FIX_SCALE; - } - - protected int FixMult(int a, int b) - { - return (a*b)/FIX_SCALE; - } - - protected int FixDiv(int a, int b) - { - return (a*FIX_SCALE)/b; - } - - protected int FixRound(int a) - { - return (a >= 0 ? (a+FIX_SCALE/2)/FIX_SCALE : (a-FIX_SCALE/2)/FIX_SCALE); - } - - - - /** - * pack a value ready to be written to the kernel module - * @param buf - * @param offset - * @param val - */ - protected void setVal(byte[] buf, int offset, int val) - { - buf[offset] = (byte)val; - buf[offset+1] = (byte)(val >> 8); - buf[offset+2] = (byte)(val >> 16); - buf[offset+3] = (byte)(val >> 24); - } - - /** - * Set the PID control parameters in the kernel module - * @param typ - * @param moveP - * @param moveI - * @param moveD - * @param holdP - * @param holdI - * @param holdD - * @param offset - * @param deadBand - */ - public synchronized void setControlParams(int typ, float moveP, float moveI, float moveD, float holdP, float holdI, float holdD, int offset, float deadBand) - { - regCmd[0] = OUTPUT_SET_TYPE; - regCmd[1] = (byte)port; - regCmd[2] = (byte)typ; - setVal(regCmd, 3, floatToFix(moveP)); - setVal(regCmd, 7, floatToFix(moveI)); - setVal(regCmd, 11, floatToFix(moveD)); - setVal(regCmd, 15, floatToFix(holdP)); - setVal(regCmd, 19, floatToFix(holdI)); - setVal(regCmd, 23, floatToFix(holdD)); - setVal(regCmd, 27, offset); - setVal(regCmd, 31, floatToFix(deadBand)); - pwm.write(regCmd, 35); - - } - - - /** - * Check to see if the current command is complete and if needed call - * any listeners. - */ - protected synchronized void checkComplete() - { - if (started && !isMoving()) - { - started = false; - if (listener != null) - listener.rotationStopped(motor, getTachoCount(), isStalled(), System.currentTimeMillis()); - } - } - - /** - * We are starting a new move operation. Handle listeners as required - */ - protected synchronized void startNewMove() - { - if (started) - checkComplete(); - if (started) - throw new IllegalStateException("Motor must be stopped"); - started = true; - if (listener != null) - { - listener.rotationStarted(motor, getTachoCount(), false, System.currentTimeMillis()); - notifyAll(); - } - - } - - /** - * Thread to handle listeners. - */ - public synchronized void run() - { - while (true) - { - // wait until a move is actually started - while (!started) - try { - wait(); - } catch (InterruptedException e){} - checkComplete(); - try { - wait(5); - } catch (InterruptedException e){} - } - } - - /** - * Start a move using the PID loop in the kernel module - * @param t1 Time for acceleration phase - * @param t2 Time for cruise phase - * @param t3 Time for deceleration phase - * @param c2 Position (cnt) after acceleration phase - * @param c3 Position (cnt) after cruise stage - * @param v1 Velocity at start of acceleration stage - * @param v2 Velocity after acceleration stage - * @param a1 Acceleration - * @param a3 Deceleration - * @param sl stall limit - * @param st stall time - * @param ts Time stamp - * @param hold What to do after the move - */ - protected void subMove(int t1, int t2, int t3, float c1, float c2, float c3, float v1, float v2, float a1, float a3, int sl, int st, int ts, boolean hold) - { - //System.out.println("t1 " + t1 + " t2 " + t2 + " t3 " + t3 + " c1 " + c1 + " c2 " + c2 + " c3 " + c3 + " v1 " + v1 + " v2 " + v2 + " a1 " + a1 + " a3 " + a3); - // convert units from /s (i.e 100ms) to be per 1024ms to allow div to be performed by shift - v1 = (v1/1000f)*1024f; - v2 = (v2/1000f)*1024f; - a1 = (((a1/1000f)*1024f)/1000f)*1024f; - a3 = (((a3/1000f)*1024f)/1000f)*1024f; - // now start the actual move - regCmd[0] = OUTPUT_START; - regCmd[1] = (byte)port; - setVal(regCmd, 2, t1); - setVal(regCmd, 6, t2); - setVal(regCmd, 10, t3); - setVal(regCmd, 14, floatToFix(c1)); - setVal(regCmd, 18, floatToFix(c2)); - setVal(regCmd, 22, floatToFix(c3)); - setVal(regCmd, 26, floatToFix(v1)); - setVal(regCmd, 30, floatToFix(v2)); - setVal(regCmd, 34, floatToFix(a1)); - setVal(regCmd, 38, floatToFix(a3)); - setVal(regCmd, 42, sl); - setVal(regCmd, 46, st); - setVal(regCmd, 50, ts); - regCmd[54] = (byte) (hold ? 1 : 0); - // if we are going to move then tell any listeners. - if ((v1 != 0 || v2 != 0) && ts == 0) - startNewMove(); - } - - /** - * Helper method generate a move by splitting it into three phases, initial - * acceleration, constant velocity, and final deceleration. We allow for the case - * were it is not possible to reach the required constant velocity and hence the - * move becomes triangular rather than trapezoid. - * @param curVel Initial velocity - * @param curPos Initial position - * @param speed - * @param acc - * @param limit - * @param hold - */ - protected void genMove(float curVel, float curPos, float curCnt, int curTime, float speed, float acc, int limit, boolean hold) - { - // Save current move params we may need these to adjust speed etc. - float u2 = curVel*curVel; - //int len = (int)(limit - curPos); - float len = (limit - curPos); - float v = speed; - float a1 = acc; - float a3 = acc; - //System.out.println("pos " + curPos + " curVel " + curVel + " limit " + limit + " len " + len + " speed " + speed + " hold " + hold); - if (speed == 0.0) - { - // Stop case - //System.out.println("Stop"); - if (curVel < 0) - a3 = -acc; - int t3 = (int)(1000*(curVel/a3)); - subMove(0, 0, t3, 0, 0, curCnt, 0, curVel, 0, -a3, stallLimit, stallTime, curTime, hold); - return; - } - float v2 = v*v; - if (Math.abs(limit) == NO_LIMIT) - { - // Run forever, no need for deceleration at end - //System.out.println("Unlimited move"); - if (limit < 0) - v = -speed; - if (v < curVel) - a1 = -acc; - float s1 = (v2 - u2)/(2*a1); - int t1 = (int)(1000*(v - curVel)/a1); - subMove(t1, NO_LIMIT, 0, curCnt, curCnt + s1, 0, curVel, v, a1, 0, stallLimit, stallTime, curTime, hold); - return; - } - // We have some sort of target position work out how to get to it - if (curVel != 0) - { - // we need to work out if we can get to the end point in a single move - if (curVel < 0) - a3 = -acc; - float s3 = (u2)/(2*a3); - //System.out.println("stop pos " + s3); - // if final position is less than stop pos we need to reverse direction - if (len < s3) - v = -speed; - a3 = acc; - } - else - if (len < 0) - v = -speed; - if (v < curVel) - a1 = -acc; - if (v < 0) - a3 = -acc; - float vmax2 = a3*len + u2/2; - // can we ever reach target velocity? - if (vmax2 <= v2) - { - // triangular move - //System.out.println("Triangle"); - if (vmax2 < 0) System.out.println("vmax -ve" + vmax2); - if (v < 0) - v = -(float) Math.sqrt(vmax2); - else - v = (float) Math.sqrt(vmax2); - float s1 = (vmax2 - u2)/(2*a1); - int t1 = (int)(1000*(v - curVel)/a1); - int t2 = t1; - int t3 = t2 + (int)(1000*(v/a3)); - subMove(t1, t2, t3, curCnt, 0, s1+curCnt, curVel, v, a1, -a3, stallLimit, stallTime, curTime, hold); - } - else - { - // trapezoid move - //System.out.println("Trap"); - float s1 = (v2 - u2)/(2*a1); - float s3 = (v2)/(2*a3); - float s2 = len - s1 - s3; - //System.out.println("s1 " + s1 + " s2 " + s2 + " s3 " + s3); - int t1 = (int)(1000*(v - curVel)/a1); - int t2 = t1 + (int)(1000*s2/v); - int t3 = t2 + (int)(1000*(v/a3)); - //System.out.println("v " + v + " a1 " + a1 + " a3 " + (-a3)); - subMove(t1, t2, t3, curCnt, curCnt+s1, curCnt+s1+s2, curVel, v, a1, -a3, stallLimit, stallTime, curTime, hold); - - } - } - - /** - * Waits for the current move operation to complete - */ - public void waitComplete() - { - for(EV3MotorRegulatorKernelModule r : syncActive) - { - while(r.isMoving()) - Delay.msDelay(1); - } - for(EV3MotorRegulatorKernelModule r : syncActive) - r.checkComplete(); - } - - protected void executeMove() - { - // first generate all of the active moves - for(EV3MotorRegulatorKernelModule r : syncActive) - { - if (r.newMove) - r.genMove(r.curVelocity, r.curPosition, r.curCnt, (r.curState >= ST_START ? r.curTime : 0), r.curSpeed, r.curAcc, r.curLimit, r.curHold); - } - // now write them to the kernel - synchronized(pwm) - { - int cnt = 0; - for(EV3MotorRegulatorKernelModule r : syncActive) - { - if (r.newMove) - { - System.arraycopy(r.regCmd, 0, regCmd2, cnt, 55); - cnt += 55; - //pwm.write(r.regCmd, 55); - r.newMove = false; - } - } - pwm.write(regCmd2, cnt); - } - } - - - /** - * Initiate a new move and optionally wait for it to complete. - * If some other move is currently executing then ensure that this move - * is terminated correctly and then start the new move operation. - * @param speed - * @param acceleration - * @param limit - * @param hold - * @param waitComplete - */ - public void newMove(float speed, int acceleration, int limit, boolean hold, boolean waitComplete) - { - synchronized(this) - { - limitAngle = limit; - if (Math.abs(limit) != NO_LIMIT) - limit += zeroTachoCnt; - updateRegulatorInformation(); - // Ignore repeated commands - if (curState != ST_STALL && !waitComplete && (speed == curSpeed) && (curAcc == acceleration) && (curLimit == limit) && (curHold == hold)) - return; - // save the move parameters - curSpeed = speed; - curHold = hold; - curAcc = acceleration; - curLimit = limit; - newMove = true; - executeMove(); - } - if (waitComplete) - waitComplete(); - } - - /** - * The kernel module updates the shared memory serial number every time - * a new command is issued. We can use this to wait for the shared mem - * to be updated. We must do this to ensure that we do not see a move - * as complete when in fact it may not have even started yet! - * @return - */ - protected int getSerialNo() - { - synchronized(ibuf) - { - return ibuf.get(port*8 + 7); - } - } - - /** - * Grabs the current state of the regulator and stores in class - * member variables - */ - protected void updateRegulatorInformation() - { - int time; - int time2; - // if there are no active regulators nothing to do - if (syncActive.length <= 0) return; - synchronized(ibufShadow) - { - // Check to make sure time is not changed during read - do { - // TODO: sort out how to handle JIT issues and shared memory. - // The problem is that when the JIT compiler gets to work - // it ends up seeing the shared memory as a simple array. - // It is not possible to label this array as volatile so - // some of the following code is seen as invariant and so can be - // optimised. Adding the synchronized section seems to help - // with this but it is not ideal. Need a better solution if possible - synchronized(ibuf) - { - // copy the main buffer to the shadow to freeze the state - ibuf.rewind(); - time = ibuf.get(port*8 + 5); - ibuf.get(ibufShadow.array()); - time2 = ibuf.get(port*8 + 6); - } - } while (time != time2); - // now cache the values in the active regulators - for(EV3MotorRegulatorKernelModule r : syncActive) - { - final int base = r.port*8; - r.curCnt = FixToFloat(ibufShadow.get(base+1)); - r.curPosition = r.curCnt + ibufShadow.get(base); - r.curVelocity = (FixToFloat(ibufShadow.get(base+2))/1024)*1000; - r.curTime = ibufShadow.get(base + 5); - r.curState = ibufShadow.get(base + 4); - r.curTachoCnt = ibufShadow.get(base+3) - zeroTachoCnt; - r.curSerial = ibufShadow.get(base + 7); - } - } - } - - /** - * returns the current position from the regulator - * @return current position in degrees - */ - public synchronized float getPosition() - { - updateRegulatorInformation(); - return curPosition - zeroTachoCnt; - } - - /** - * returns the current velocity from the regulator - * @return velocity in degrees per second - */ - public synchronized float getCurrentVelocity() - { - updateRegulatorInformation(); - return curVelocity; - } - - - /** - * return the regulator state. - * @return - */ - protected int getRegState() - { - if (syncActive.length <= 0) return curState; - synchronized(ibuf) - { - curState = ibuf.get(port*8 + 4); - return curState; - } - } - - public boolean isMoving() - { - return getRegState() >= ST_START; - } - - public boolean isStalled() - { - return getRegState() == ST_STALL; - } - - public int getTachoCount() - { - if (syncActive.length <= 0) return curTachoCnt; - return EV3MotorPort.this.getTachoCount() - zeroTachoCnt; - } - - public void resetTachoCount() - { - zeroTachoCnt = EV3MotorPort.this.getTachoCount(); - } - - - public void setStallThreshold(int error, int time) - { - this.stallLimit = error; - this.stallTime = time; - } - - - /** - * The target speed has been changed. Reflect this change in the - * regulator. - * @param newSpeed new target speed. - */ - public synchronized void adjustSpeed(float newSpeed) - { - if (curSpeed != 0 && newSpeed != curSpeed) - { - updateRegulatorInformation(); - if (curState >= ST_START && curState <= ST_MOVE) - { - curSpeed = newSpeed; - newMove = true; - executeMove(); - } - } - } - - /** - * The target acceleration has been changed. Updated the regulator. - * @param newAcc - */ - public synchronized void adjustAcceleration(int newAcc) - { - if (newAcc != curAcc) - { - updateRegulatorInformation(); - if (curState >= ST_START && curState <= ST_MOVE) - { - curAcc = newAcc; - newMove = true; - executeMove(); - } - } - } - - - @Override - public void setControlParamaters(int typ, float moveP, float moveI, - float moveD, float holdP, float holdI, float holdD, int offset) - { - setControlParams(typ, moveP, moveI, moveD, holdP, holdI, holdD, offset, 0.5f); - } - - - - @Override - public void addListener(RegulatedMotor motor, RegulatedMotorListener listener) - { - this.motor = motor; - this.listener = listener; - if (getState() == Thread.State.NEW) - start(); - } - - - @Override - public RegulatedMotorListener removeListener() - { - RegulatedMotorListener old = listener; - listener = null; - return old; - } - - - @Override - public int getLimitAngle() - { - return limitAngle; - } - - public synchronized void synchronizeWith(MotorRegulator[] syncList) - { - // validate the list - for(MotorRegulator r : syncList) - { - if (! (r instanceof EV3MotorRegulatorKernelModule)) - throw new IllegalArgumentException("Invalid regulator class - is it remote?"); - if (r == this) - throw new IllegalArgumentException("Can't synchronize with self"); - } - // create new array and add self into it - EV3MotorRegulatorKernelModule[] sl = new EV3MotorRegulatorKernelModule[syncList.length+1]; - int i = 1; - for(MotorRegulator r : syncList) - sl[i++] = (EV3MotorRegulatorKernelModule)r; - sl[0] = this; - this.syncWith = sl; - } - - public synchronized void startSynchronization() - { - synchronized(pwm) - { - // set slaves to sync - for(int i = 1; i < syncWith.length; i++) - syncWith[i].syncActive = syncSlave; - this.syncActive = this.syncWith; - this.updateRegulatorInformation(); - this.syncActive = syncSlave; - } - } - - public synchronized void endSynchronization(boolean immRet) - { - synchronized(pwm) - { - // execute all synchronized operations - syncActive = syncWith; - executeMove(); - // reset operations back to normal for slaves - for(int i = 1; i < syncWith.length; i++) - syncWith[i].syncActive = syncWith[i].syncThis; - } - if (!immRet) - waitComplete(); - // set master back to normal operation - syncActive = syncThis; - } - } - - /** {@inheritDoc} - */ - @Override - public boolean open(int typ, int port, EV3Port ref) - { - if (!super.open(typ, port, ref)) - return false; - cmd[0] = OUTPUT_CONNECT; - cmd[1] = (byte) port; - pwm.write(cmd, 2); - return true; - } - - /** {@inheritDoc} - */ - @Override - public void close() - { - cmd[0] = OUTPUT_DISCONNECT; - cmd[1] = (byte) port; - pwm.write(cmd, 2); - super.close(); - } - - - - /** - * Helper method to adjust the requested power - * @param power - */ - protected void setPower(int power) - { - cmd[0] = OUTPUT_POWER; - cmd[1] = (byte) port; - cmd[2] = (byte) power; - pwm.write(cmd, 3); - } - - /** - * Helper method stop the motor - * @param flt - */ - protected void stop(boolean flt) - { - cmd[0] = OUTPUT_STOP; - cmd[1] = (byte) port; - cmd[2] = (byte) (flt ? 0 : 1); - pwm.write(cmd, 3); - - } - - - /** - * Low-level method to control a motor. - * - * @param power power from 0-100 - * @param mode defined in BasicMotorPort. 1=forward, 2=backward, 3=stop, 4=float. - * @see BasicMotorPort#FORWARD - * @see BasicMotorPort#BACKWARD - * @see BasicMotorPort#FLOAT - * @see BasicMotorPort#STOP - */ - public synchronized void controlMotor(int power, int mode) - { - // Convert lejos power and mode to EV3 power and mode - if (mode >= STOP) - { - power = 0; - stop(mode == FLOAT); - } - else - { - if (mode == BACKWARD) - power = -power; - setPower(power); - } - curMode = mode; - } - - - /** - * returns tachometer count - */ - public int getTachoCount() - { - synchronized(ibuf) - { - return ibuf.get(port*8 + 3); - } - } - - - /** - *resets the tachometer count to 0; - */ - public synchronized void resetTachoCount() - { - cmd[0] = OUTPUT_CLR_COUNT; - cmd[1] = (byte)port; - pwm.write(cmd, 2); - } - - public void setPWMMode(int mode) - { - } - - - private static void initDeviceIO() - { - tacho = new NativeDevice("/dev/lms_motor"); - bbuf = tacho.mmap(4*8*4).getByteBuffer(0, 4*8*4); - //System.out.println("direct " + bbuf.isDirect()); - ibuf = bbuf.asIntBuffer(); - // allocate the shadow buffer - ibufShadow = IntBuffer.allocate(4*8); - pwm = new NativeDevice("/dev/lms_pwm"); - } - - /** - * {@inheritDoc} - */ - @Override - public synchronized MotorRegulator getRegulator() - { - if (regulator == null) - regulator = new EV3MotorRegulatorKernelModule(this); - //regulator = new JavaMotorRegulator(this); - return regulator; - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Port.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Port.java deleted file mode 100644 index cbfadfe..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Port.java +++ /dev/null @@ -1,78 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.DeviceException; -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.ConfigurationPort; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.port.UARTPort; -import lejos.hardware.sensor.EV3SensorConstants; - -public class EV3Port implements Port -{ - public static final int SENSOR_PORT = 0; - public static final int MOTOR_PORT = 1; - protected String name; - protected int typ; - protected int portNum; - - public EV3Port(String name, int typ, int portNum) - { - if (typ < SENSOR_PORT || typ > MOTOR_PORT) - throw new IllegalArgumentException("Invalid port type"); - if (portNum < 0 || - (typ == SENSOR_PORT && portNum >= EV3SensorConstants.PORTS) || - (typ == MOTOR_PORT && portNum >= EV3SensorConstants.MOTORS)) - throw new IllegalArgumentException("Invalid port number"); - this.name = name; - this.typ = typ; - this.portNum = portNum; - - } - - /** {@inheritDoc} - */ - @Override - public String getName() - { - return name; - } - - /** {@inheritDoc} - */ - @Override - public T open(Class portclass) - { - EV3IOPort p = null; - switch(typ) - { - case SENSOR_PORT: - if (portclass == UARTPort.class) - p = new EV3UARTPort(); - else if (portclass == AnalogPort.class) - p = new EV3AnalogPort(); - else if (portclass == I2CPort.class) - p = new EV3I2CPort(); - else if (portclass == ConfigurationPort.class) - p = new EV3ConfigurationPort(); - break; - case MOTOR_PORT: - if (portclass == BasicMotorPort.class) - p = new EV3MotorPort(); - else if (portclass == TachoMotorPort.class) - p = new EV3MotorPort(); - else if (portclass == ConfigurationPort.class) - p = new EV3ConfigurationPort(); - // TODO: Should we also allow Encoder? - break; - } - if (p == null) - throw new IllegalArgumentException("Invalid port interface"); - if (!p.open(typ, portNum, this)) - throw new DeviceException("unable to open port"); - return portclass.cast(p); - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3TextLCD.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3TextLCD.java deleted file mode 100644 index 455942a..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3TextLCD.java +++ /dev/null @@ -1,143 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.TextLCD; - -public class EV3TextLCD extends EV3LCD implements TextLCD { - private Font font; - - public EV3TextLCD(String layerName, Font font) { - super(layerName); - this.font = font; - } - - public EV3TextLCD(String layerName) { - this(layerName, Font.getDefaultFont()); - } - - /** - * Draw a single char on the LCD at specified x,y co-ordinate. - * @param c Character to display - * @param x X location - * @param y Y location - */ - public void drawChar(char c, int x, int y) - { - bitBlt(font.glyphs, font.width * font.glyphCount, font.height, font.width * (c-32), 0, x * font.glyphWidth, y * font.height, font.width, font.height, ROP_COPY); - } - - /** - * Display a string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawString(String str, int x, int y) - { - char[] strData = str.toCharArray(); - // Draw the background rect - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, x * font.glyphWidth, y * font.height, strData.length * font.glyphWidth, font.height, ROP_CLEAR); - // and the characters - for (int i = 0; (i < strData.length); i++) - bitBlt(font.glyphs, font.width * font.glyphCount, font.height, font.width * (strData[i]-32), 0, (x + i) * font.glyphWidth, y * font.height, font.width, font.height, ROP_COPY); - } - - - /** - * Display an int on the LCD at specified x,y co-ordinate. - * - * @param i The value to display. - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawInt(int i, int x, int y) - { - drawString(Integer.toString(i), x, y); - } - - /** - * Display an in on the LCD at x,y with leading spaces to occupy at least the number - * of characters specified by the places parameter. - * - * @param i The value to display - * @param places number of places to use to display the value - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - */ - public void drawInt(int i, int places, int x, int y) - { - drawString(String.format("%"+places+"d", i), x, y); - } - - /** - * Display an optionally inverted string on the LCD at specified x,y co-ordinate. - * - * @param str The string to be displayed - * @param x The x character co-ordinate to display at. - * @param y The y character co-ordinate to display at. - * @param inverted if true the string is displayed inverted. - */ - public void drawString(String str, int x, int y, boolean inverted) - { - if (inverted) - { - char[] strData = str.toCharArray(); - // Draw the background rect - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, x * font.glyphWidth, y * font.height, strData.length * font.glyphWidth, font.height, ROP_SET); - // and the characters - for (int i = 0; (i < strData.length); i++) - bitBlt(font.glyphs, font.width * font.glyphCount, font.height, font.width * (strData[i]-32), 0, (x + i) * font.glyphWidth, y * font.height, font.width, font.height, ROP_COPYINVERTED); - } else - drawString(str, x, y); - } - - /** - * Scrolls the screen up one text line - * - */ - public void scroll() - { - bitBlt(displayBuf, SCREEN_WIDTH, SCREEN_HEIGHT, 0, font.height, - 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - font.height, ROP_COPY); - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, SCREEN_HEIGHT - font.height, - SCREEN_WIDTH, font.height, ROP_CLEAR); - } - - - /** - * Clear a contiguous set of characters - * @param x the x character coordinate - * @param y the y character coordinate - * @param n the number of characters - */ - public void clear(int x, int y, int n) { - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, x * font.glyphWidth, y * font.height, - n * font.glyphWidth, font.height, ROP_CLEAR); - } - - /** - * Clear an LCD display row - * @param y the row to clear - */ - public void clear(int y) { - bitBlt(null, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, y * font.height, - SCREEN_WIDTH, font.height, ROP_CLEAR); - } - - @Override - public Font getFont() { - return font; - } - - @Override - public int getTextWidth() { - return getWidth() / font.width; - } - - @Override - public int getTextHeight() { - return getHeight() / font.height; - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3UARTPort.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3UARTPort.java deleted file mode 100644 index bd3915c..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3UARTPort.java +++ /dev/null @@ -1,722 +0,0 @@ -package lejos.internal.ev3; - -import java.io.IOError; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.List; - -import com.sun.jna.Pointer; -import com.sun.jna.Structure; - -import lejos.hardware.DeviceException; -import lejos.hardware.port.UARTPort; -import lejos.internal.io.NativeDevice; -import lejos.utility.Delay; - -/** - * Provide access to EV3 sensor ports operating in UART mode.

    - * A mechanism is provided to allow access to the RAW UART device - * allowing simple read/write operations. This RAW mode disables - * the normal Lego protocol used to communicate with Lego UART - * sensors

    - * NOTE: This code is not pretty! The interface uses a number of structures mapped - * into memory from the device. I am not aware of any clean way to implement this - * interface in Java. So for now multiple pointers to bytes/ints array etc. are used this - * means that the actual offsets of the start of the C arrays needs to be obtained - * and these (along with various sizes) are currently hard-coded as "OFF" values below. - * I'm sure there must be a better way! Also note that there seem to be a large - * number of potential race conditions in the device initialisation stage hence the - * various loops needed to retry operations. - * @author andy - * - */ -public class EV3UARTPort extends EV3IOPort implements UARTPort -{ - protected static NativeDevice uart; - protected static Pointer pDev; - protected static ByteBuffer devStatus; - protected static ByteBuffer raw; - protected static ByteBuffer actual; - protected static final int DEV_SIZE = 42744; - protected static final int DEV_STATUS_OFF = 42608; - protected static final int DEV_RAW_OFF = 4192; - protected static final int DEV_RAW_SIZE1 = 9600; - protected static final int DEV_RAW_SIZE2 = 32; - protected static final int DEV_ACTUAL_OFF = 42592; - - protected static final int UART_CONNECT = 0xc0037507; - protected static final int UART_DISCONNECT = 0xc0037508; - protected static final int UART_SETMODE = 0xc0037509; - protected static final int UART_SET_CONN = 0xc00c7500; - protected static final int UART_READ_MODE_INFO = 0xc03c7501; - protected static final int UART_NACK_MODE_INFO = 0xc03c7502; - protected static final int UART_CLEAR_CHANGED = 0xc03c7503; - protected static final int UART_SET_CONFIG = 0xc0087504; - protected static final int UART_RAW_READ = 0xc0047505; - protected static final int UART_RAW_WRITE = 0xc0047506; - - - protected static final byte UART_PORT_CHANGED = 1; - protected static final byte UART_DATA_READY = 8; - protected static final byte UART_PORT_ERROR = (byte)0x80; - - protected static final int TIMEOUT_DELTA = 1; - protected static final int TIMEOUT = 4000; - protected static final int INIT_DELAY = 5; - protected static final int INIT_RETRY = 100; - protected static final int OPEN_RETRY = 5; - - protected static final int RAW_BUFFER_SIZE = 255; - - static { - initDeviceIO(); - } - - /** - * The following class maps directly to a C structure containing device information. - * @author andy - * - */ - public static class TYPES extends Structure - { - public byte Name[] = new byte[12]; - public byte Type; - public byte Connection; - public byte Mode; - public byte DataSets; - public byte Format; - public byte Figures; - public byte Decimals; - public byte Views; - public float RawMin; - public float RawMax; - public float PctMin; - public float PctMax; - public float SiMin; - public float SiMax; - public short InvalidTime; - public short IdValue; - public byte Pins; - public byte[] Symbol = new byte[5]; - public short Align; - @Override - protected List getFieldOrder() - { - // TODO Auto-generated method stub - return Arrays.asList(new String[] {"Name", - "Type", - "Connection", - "Mode", - "DataSets", - "Format", - "Figures", - "Decimals", - "Views", - "RawMin", - "RawMax", - "PctMin", - "PctMax", - "SiMin", - "SiMax", - "InvalidTime", - "IdValue", - "Pins", - "Symbol", - "Align"}); - } - - /* - public TYPES() - { - this.setAlignType(Structure.ALIGN_DEFAULT); - }*/ - } - - public static class UARTCTL extends Structure - { - public TYPES TypeData; - public byte Port; - public byte Mode; - - public UARTCTL() - { - //this.setAlignType(Structure.ALIGN_DEFAULT); - //System.out.println("size is " + size()); - } - - @Override - protected List getFieldOrder() - { - // TODO Auto-generated method stub - return Arrays.asList(new String[] {"TypeData", - "Port", - "Mode"}); - } - - } - - public static class UARTCONFIG extends Structure - { - public int Port; - public int BitRate; - @Override - protected List getFieldOrder() - { - // TODO Auto-generated method stub - return Arrays.asList(new String[] { - "Port", - "BitRate"}); - } - } - - protected TYPES[] modeInfo = new TYPES[UART_MAX_MODES]; - protected int modeCnt = 0; - protected byte[] rawInput; - protected byte[] rawOutput; - protected byte[] cmd = new byte[3]; - - /** - * return the current status of the port - * @return status - */ - protected byte getStatus() - { - synchronized(devStatus) - { - return devStatus.get(port); - } - } - - protected void setStatus(int newStatus) - { - devStatus.put(port, (byte)newStatus); - } - - /** - * Wait for the port status to become non zero, or for the operation to timeout - * @param timeout timeout period in ms - * @return port status or 0 if the operation timed out - */ - protected byte waitNonZeroStatus(int timeout) - { - int cnt = timeout/TIMEOUT_DELTA; - byte status = getStatus(); - while (cnt-- > 0) - { - if (status != 0) - return status; - Delay.msDelay(TIMEOUT_DELTA); - status = getStatus(); - } - //System.out.println("NZS Timeout"); - return status; - } - - /** - * Wait for the port status to become zero - * @param timeout timeout period in ms - * @return zero if successful or the current status if timed out - */ - protected byte waitZeroStatus(int timeout) - { - int cnt = timeout/TIMEOUT_DELTA; - byte status = getStatus(); - while (cnt-- > 0) - { - if (status == 0) - return status; - Delay.msDelay(TIMEOUT_DELTA); - status = getStatus(); - } - //System.out.println("ZS Timeout"); - return status; - } - - /** - * Connect to the device - */ - protected void connect() - { - cmd[0] = (byte)port; - uart.ioctl(UART_CONNECT, cmd); - } - - /** - * Disconnect to the device - */ - protected void disconnect() - { - cmd[0] = (byte)port; - uart.ioctl(UART_DISCONNECT, cmd); - } - - /** - * reset the port and device - */ - protected void reset() - { - // Force the device to reset - disconnect(); - connect(); - } - - /** - * Set the current operating mode - * @param mode - */ - protected void setOperatingMode(int mode) - { - cmd[0] = (byte)port; - cmd[2] = (byte)mode; - uart.ioctl(UART_SETMODE, cmd); - } - - /** - * Read the mode information for the specified operating mode. - * @param mode mode number to read - * @param uc control structure to read the data into - * @return - */ - protected boolean getModeInfo(int mode, UARTCTL uc) - { - uc.Port = (byte)port; - uc.Mode = (byte)mode; - uc.write(); - //System.out.println("size is " + uc.size() + " TYPES " + uc.TypeData.size() + " ptr " + uc.getPointer().SIZE); - uart.ioctl(UART_READ_MODE_INFO, uc.getPointer()); - uc.read(); - //System.out.println("name[0]" + uc.TypeData.Name[0]); - return uc.TypeData.Name[0] != 0; - } - - /** - * Clear the flag that indicates the mode info has been cached. This - * allows us to read the same infomration again later without having to - * reset the device. - * @param mode mode number to read - * @param uc control structure to read the data into - * @return - */ - protected void clearModeCache(int mode, UARTCTL uc) - { - uc.Port = (byte)port; - uc.Mode = (byte)mode; - uc.write(); - //System.out.println("size is " + uc.size() + " TYPES " + uc.TypeData.size() + " ptr " + uc.getPointer().SIZE); - uart.ioctl(UART_NACK_MODE_INFO, uc.getPointer()); - } - - /** - * Clear the port changed flag for the current port. - */ - protected void clearPortChanged(UARTCTL uc) - { - //System.out.printf("Clear changed\n"); - uc.Port = (byte)port; - uc.write(); - uart.ioctl(UART_CLEAR_CHANGED, uc.getPointer()); - devStatus.put(port, (byte)(devStatus.get(port) & ~UART_PORT_CHANGED)); - } - - /** - * Read the mode information from the port. return true - * @return - */ - protected boolean readModeInfo() - { - //long base = System.currentTimeMillis(); - modeCnt = 0; - for(int i = 0; i < UART_MAX_MODES; i++) - { - UARTCTL uc = new UARTCTL(); - if (getModeInfo(i, uc)) - { - clearModeCache(i, uc); - modeInfo[i] = uc.TypeData; - modeCnt++; - } - else - modeInfo[i] = null; - } - //System.out.println("Got " + modeCnt + " entries time " + (System.currentTimeMillis() - base)); - return modeCnt > 0; - - } - /** - * Attempt to initialise the sensor ready for use. - * @param mode initial operating mode - * @return -1 no uart, 0 failed to initialise, 1 sensor initialised - */ - protected int initSensor(int mode) - { - byte status; - int retryCnt = 0; - //System.out.println("Initial status is " + getStatus() + " type is " + ldm.getPortType(port)); - //long base = System.currentTimeMillis(); - UARTCTL uc = new UARTCTL(); - // now try and configure as a UART - setOperatingMode(mode); - status = waitNonZeroStatus(TIMEOUT); - //System.out.println("Time is " + (System.currentTimeMillis() - base)); - if ((status & UART_PORT_ERROR) != 0) return -1; - while((status & UART_PORT_CHANGED) != 0 && retryCnt++ < INIT_RETRY) - { - // something change wait for it to become ready - clearPortChanged(uc); - Delay.msDelay(INIT_DELAY); - status = waitNonZeroStatus(TIMEOUT); - //System.out.println("Time2 is " + (System.currentTimeMillis() - base)); - if ((status & UART_DATA_READY) != 0 && (status & UART_PORT_CHANGED) == 0) - { - // device ready make sure it is now in the correct mode - setOperatingMode(mode); - status = waitNonZeroStatus(TIMEOUT); - //System.out.println("Time3 is " + (System.currentTimeMillis() - base)); - } - } - //System.out.println("Init complete retry " + retryCnt + " time " + (System.currentTimeMillis() - base)); - if ((status & UART_DATA_READY) != 0 && (status & UART_PORT_CHANGED) == 0) - return 1; - else - return 0; - } - - /** {@inheritDoc} - */ - @Override - public boolean initialiseSensor(int mode) - { - connect(); - for(int i = 0; i < OPEN_RETRY; i++) - { - // initialise the sensor, if we have no mode data - // then read it, otherwise use what we have - int res = initSensor(mode); - if (res < 0) break; - if (res > 0 && (modeCnt > 0 || readModeInfo())) - { - //System.out.println("reset cnt " + i); - return super.setMode(mode); - } - resetSensor(); - } - disconnect(); - return false; - } - - /** {@inheritDoc} - */ - @Override - public void resetSensor() - { - reset(); - waitZeroStatus(TIMEOUT); - } - - - - /** {@inheritDoc} - */ - @Override - public boolean open(int typ, int port, EV3Port ref) - { - if (!super.open(typ, port, ref)) - return false; - // clear mode data cache - modeCnt = 0; - return true; - } - - /** {@inheritDoc} - */ - @Override - public void close() - { - disconnect(); - super.close(); - } - - /** - * Set the current operating mode - * @param mode new mode to set - * @return true if the mode is set, false if the operation failed - */ - public boolean setMode(int mode) - { - //System.out.println("Set mode " + mode); - // are we initialised ? - if (modeCnt <= 0) - return initialiseSensor(mode); - if (modeInfo[mode] == null) - return false; - //long s = System.currentTimeMillis(); - //System.out.println("Mode is " + getModeName(mode)); - setOperatingMode(mode); - //System.out.println("status is " + getStatus()); - int status = waitNonZeroStatus(TIMEOUT); - boolean ret; - if ((status & UART_DATA_READY) != 0 && (status & UART_PORT_CHANGED) == 0) - ret = super.setMode(mode); - else - { - // Sensor may have reset try and initialise it in the new mode. - ret = initialiseSensor(mode); - //System.out.println("reset"); - } - if (ret) - { - //ret = waitDataUpdate(TIMEOUT); - //System.out.println("time " + (System.currentTimeMillis() - s)); - } - return ret; - } - - /** - * The RAW data is held in a circular buffer with 32 bytes of data per entry - * and 300 entries per port. This method calculates the byte offset of the - * latest data value read into the buffer. - * @return offset of the current data - */ - private int calcRawOffset() - { - synchronized (actual) - { - int ret = port*DEV_RAW_SIZE1 + actual.getShort(port*2)*DEV_RAW_SIZE2; - return ret; - } - } - - - /** - * Wait for a new data point to be added to the data set. Return true if - * new data is available, false if not - * @param timeout - * @return true if updated - */ - protected boolean waitDataUpdate(int timeout) - { - int cnt = timeout/TIMEOUT_DELTA; - int offset = calcRawOffset(); - //System.out.println("offset1 " + actual.getShort(port*2)); - while (cnt-- > 0) - { - if (calcRawOffset() != offset) - { - //System.out.println("offset " + actual.getShort(port*2)); - return true; - } - Delay.msDelay(TIMEOUT_DELTA); - } - return false; - } - - /** - * Check the sensor status, and if possible recover any from any error. - * If everything fails throw an exception - */ - protected void checkSensor() - { - if ((getStatus() & UART_PORT_CHANGED) != 0) - { - //System.out.println("port " + port + " Changed "); - // try and reinitialze it - if (!initialiseSensor(getMode())) - throw new DeviceException("Sensor changed unable to reset"); - - } - - } - /** - * read a single byte from the device - * @return the byte value - */ - public byte getByte() - { - checkSensor(); - return raw.get(calcRawOffset()); - } - - /** - * read a number of bytes from the device - * @param vals byte array to accept the data - * @param offset offset at which to store the data - * @param len number of bytes to read - */ - public void getBytes(byte [] vals, int offset, int len) - { - checkSensor(); - int loc = calcRawOffset(); - for(int i = 0; i < len; i++) - vals[i+offset] = raw.get(loc + i); - } - - /** - * read a single short from the device. - * @return the short value - */ - public int getShort() - { - checkSensor(); - return raw.getShort(calcRawOffset()); - } - - /** - * read a number of shorts from the device - * @param vals short array to accept the data - * @param offset offset at which to store the data - * @param len number of shorts to read - */ - public void getShorts(short [] vals, int offset, int len) - { - checkSensor(); - int loc = calcRawOffset(); - for(int i = 0; i < len; i++) - vals[i+offset] = raw.getShort(loc + i*2); - } - - /** - * Get the string name of the specified mode.

    - * TODO: Make other mode data available. - * @param mode mode to lookup - * @return String version of the mode name - */ - public String getModeName(int mode) - { - if (modeInfo[mode] != null) - { - byte[] name = modeInfo[mode].Name; - // find the length of the possibly null terminated ascii string - int len = name.length; - for(int i = 0; i < name.length; i++) - if (name[i] == 0) - len = i; - return new String(name, 0, len, Charset.forName("US-ASCII")).trim(); - } - else - return "Unknown"; - } - - - /** - * Write bytes to the sensor - * @param buffer bytes to be written - * @param offset offset to the start of the write - * @param len length of the write - * @return number of bytes written - */ - public int write(byte[] buffer, int offset, int len) { - byte[] command = new byte[len + 1]; - command[0] = (byte) port; - System.arraycopy(buffer, offset, command, 1, len); - int ret = uart.write(command, command.length); - if (ret > 0) ret--; - return ret; - } - - /** - * Return the current sensor reading to a string. - */ - public String toString() - { - float divTable[] = {1f, 10f, 100f, 1000f, 10000f, 100000f}; - TYPES info = modeInfo[currentMode]; - float val; - switch(info.Format) - { - case 0: - if (info.RawMin >= 0) - val = getByte() & 0xff; - else - val = getByte(); - break; - case 1: - if (info.RawMin >= 0) - val = getShort() & 0xffff; - else - val = getShort(); - break; - // TODO: Sort out other formats - default: - val = 0.0f; - } - val = val/divTable[info.Decimals]; - String format = "%" + info.Figures + "." + info.Decimals + "f" + new String(info.Symbol); - return String.format(format, val); - } - - /** - * Set the bit rate of the port when operating in RAW mode. - * @param bitRate The new bit rate - */ - public void setBitRate(int bitRate) - { - UARTCONFIG uc = new UARTCONFIG(); - uc.Port = port; - uc.BitRate = bitRate; - uc.write(); - uart.ioctl(UART_SET_CONFIG, uc.getPointer()); - } - - /** - * Read bytes from the uart port. If no bytes are available return 0.

    - * Note: The port must have been set into RAW mode to use this method. - * @param buffer The buffer to store the read bytes - * @param offset The offset at which to start storing the bytes - * @param len The maximum number of bytes to read - * @return The actual number of bytes read - */ - public int rawRead(byte[] buffer, int offset, int len) - { - if (rawInput == null) - rawInput = new byte[RAW_BUFFER_SIZE+2]; - rawInput[0] = (byte)port; - if (len > RAW_BUFFER_SIZE) - len = RAW_BUFFER_SIZE; - rawInput[1] = (byte)len; - len = uart.ioctl(UART_RAW_READ, rawInput); - System.arraycopy(rawInput, 2, buffer, offset, len); - return len; - } - - /** - * Attempt to write a series of bytes to the uart port. This call - * is non-blocking if there is no space in the write buffer a count - * of 0 is returned.

    - * Note: The port must have been set into RAW mode before attempting - * to use the method. - * @param buffer The buffer containing the bytes to write - * @param offset The offset of the first byte - * @param len The number of bytes to attempt to write - * @return The actual number of bytes written - */ - public int rawWrite(byte[] buffer, int offset, int len) - { - if (rawInput == null) - rawOutput = new byte[RAW_BUFFER_SIZE+2]; - rawOutput[0] = (byte)port; - if (len > RAW_BUFFER_SIZE) - len = RAW_BUFFER_SIZE; - rawOutput[1] = (byte)len; - System.arraycopy(buffer, offset, rawOutput, 2, len); - len = uart.ioctl(UART_RAW_WRITE, rawOutput); - return len; - } - - - - private static void initDeviceIO() - { - try { - uart = new NativeDevice("/dev/lms_uart"); - pDev = uart.mmap(DEV_SIZE); - } - catch (IOError e) - { - throw new UnsupportedOperationException("Unable to access EV3 hardware. Is this an EV3?", e); - } - devStatus = pDev.getByteBuffer(DEV_STATUS_OFF, PORTS); - actual = pDev.getByteBuffer(DEV_ACTUAL_OFF, PORTS*2); - raw = pDev.getByteBuffer(DEV_RAW_OFF, PORTS*DEV_RAW_SIZE1); - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Video.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Video.java deleted file mode 100644 index 439c252..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Video.java +++ /dev/null @@ -1,102 +0,0 @@ -package lejos.internal.ev3; - -import lejos.hardware.video.Video; - -/** - * Class to provide access to a Webcam attached to the EV3 - * @author Gabriel Ferrer, Andy - * - */ -public class EV3Video implements Video { - // Causes the native library to be loaded from the system. - static {System.loadLibrary("ev3video");} - - // Three primary methods for use by clients: - - /** - * Open the device and make it available for use, specify the desired frame size. Note that the actual - * frame size may be adjusted to conform to the capabilities of the device. - * @param w the desired frame width - * @param h the desired frame height - * @param format desired pixel format - * @param field desired field layout - * @throws java.io.IOException - */ - public void open(int w, int h, int format, int field, int fps) throws java.io.IOException { - width = w; - height = h; - this.format = format; - this.field = field; - this.fps = fps; - bufferSize = setup(); - } - - /** - * Open the device and make it available for use, specify the desired frame size. Note that the actual - * frame size may be adjusted to conform to the capabilities of the device. The format of the pixel - * will be YUYV and the fields will be interlaced. - * @param w the desired frame width - * @param h the desired frame height - * @throws java.io.IOException - */ - public void open(int w, int h) throws java.io.IOException { - open(w, h, PIX_FMT_YUYV, FIELD_INTERLACED, 0); - } - - /** - * Grab a single frame from the device and store the image into the supplied array - * @param frame array to store the frame - * @throws java.io.IOException - */ - public int grabFrame(byte[] frame) throws java.io.IOException { - return grab(frame); - } - - /** - * Close the webcam, the device will not be availabe after this call - * @throws java.io.IOException - */ - public void close() throws java.io.IOException { - dispose(); - } - - // Three native method stubs, all private: - - // Called by start() before any frames are grabbed. - private native int setup() throws java.io.IOException; - - // Called by grabFrame(), which creates a new buffer each time. - private native int grab(byte[] img) throws java.io.IOException; - - // Called by end() to clean things up. - private native void dispose() throws java.io.IOException; - - // Specified by the user, and retained for later reference. - private int width, height; - private int format, field; - private int bufferSize; - private int fps; - - // Utility methods - private int getBufferSize() {return bufferSize;} - - /** - * Create a byte array suitable for holding a single video frame - * @return the frame array - */ - public byte[] createFrame() {return new byte[getBufferSize()];} - - /** - * Return the frame width - * @return width in pixels - */ - public int getWidth() {return width;} - - /** - * return the frame height - * @return height in pixels - */ - public int getHeight() {return height;} - - - } \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/ev3/EV3Wrapper.java b/ev3classes/src/main/java/lejos/internal/ev3/EV3Wrapper.java deleted file mode 100644 index 340bcf3..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/EV3Wrapper.java +++ /dev/null @@ -1,201 +0,0 @@ -package lejos.internal.ev3; - -import java.io.OutputStream; -import java.io.PrintStream; -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import lejos.hardware.Button; -import lejos.hardware.Keys; -import lejos.hardware.Sound; -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.LCDOutputStream; -import lejos.hardware.lcd.TextLCD; -import lejos.internal.ev3.EV3LCDManager.LCDLayer; -import lejos.utility.Delay; - -public class EV3Wrapper implements UncaughtExceptionHandler { - - static LCDLayer systemLayer; - static EV3LCDManager manager = EV3LCDManager.getLocalLCDManager(); - static PrintStream origErr; - - public static void main(String[] args) throws Exception { - Thread.setDefaultUncaughtExceptionHandler(new EV3Wrapper()); - // Force LCD layer to be created - LocalEV3.get().getTextLCD(); - // Create extra LCD layers for redirected output, exceptions and our use - LocalEV3.get().getTextLCD(); - manager.newLayer("STDOUT"); - manager.newLayer("EXCEPTION"); - systemLayer = manager.newLayer("SYSTEM"); - // redirect standard I/O streams - TextLCD stdOut = new EV3TextLCD("STDOUT"); - OutputStream lcdOut = new LCDOutputStream(stdOut); - origErr = System.err; - System.setOut(new RedirectStream(System.out, lcdOut)); - System.setErr(new RedirectStream(System.err, lcdOut)); - // make sure everything can be seen - switchToLayer("*"); - // allow switching - new LCDLayerSwitcher().start(); - // run the original class - invokeClass(args[0], new String[0]); - } - - private static void invokeClass(String name, String[] args) - throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ - Class c = Class.forName(name); - Method m = c.getMethod("main", new Class[] { args.getClass() }); - m.setAccessible(true); - int mods = m.getModifiers(); - - if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || - !Modifier.isPublic(mods)) { - throw new NoSuchMethodException("main"); - } - - try { - m.invoke(null, new Object[] { args }); - } catch (IllegalAccessException e) { - // This should not happen, as we have disabled access checks - } - } - - private static void switchToLayer(String name) - { - LCDLayer[] layers = manager.getLayers(); - // Special case "*" all layers on - if (name.equals("*")) - { - for(LCDLayer l: layers) - l.setVisible(true); - return; - } - - // turn off all layers - for(LCDLayer l: layers) - l.setVisible(false); - // find the layer and enable it - for(LCDLayer l: layers) - if (l.getName().equals(name)) - l.setVisible(true); - } - - @Override - public void uncaughtException(Thread th, Throwable t) { - Sound.buzz(); - TextLCD lcd = new EV3TextLCD("EXCEPTION", Font.getSmallFont()); - switchToLayer("EXCEPTION"); - // Get rid of invocation exception - if (t.getCause() != null) t = t.getCause(); - // Send stack trace to the menu so it goes to EV3Console etc. - t.printStackTrace(origErr); - int offset = 0; - while (true) - { - lcd.clear(); - lcd.drawString("Uncaught exception:", offset, 0); - lcd.drawString(t.getClass().getName(), offset, 2); - if (t.getMessage() != null) lcd.drawString(t.getMessage(), offset, 3); - - if (t.getCause() != null) { - lcd.drawString("Caused by:", offset, 5); - lcd.drawString(t.getCause().toString(), offset, 6); - } - - StackTraceElement[] trace = t.getStackTrace(); - for(int i=0;i<7 && i < trace.length ;i++) lcd.drawString(trace[i].toString(), offset, 8+i); - - lcd.refresh(); - int id = Button.waitForAnyEvent(); - if (id == Button.ID_ESCAPE) break; - if (id == Button.ID_LEFT) offset += 5; - if (id == Button.ID_RIGHT)offset -= 5; - if (offset > 0) offset = 0; - } - } - - static class LCDLayerSwitcher extends Thread { - - public LCDLayerSwitcher() - { - setDaemon(true); - } - /** - * Background thread which provides automatic screen updates - */ - public void run() - { - TextLCD systemLCD = new EV3TextLCD("SYSTEM", Font.getLargeFont()); - int curLayer = -1; - String layerName = "*"; - Keys keys = LocalEV3.get().getKeys(); - while (true) - { - if (keys.getButtons() == (Keys.ID_LEFT|Keys.ID_RIGHT)) - { - LCDLayer[] layers = manager.getLayers(); - curLayer++; - if (curLayer < layers.length && layers[curLayer] == systemLayer) - // skip system layer - curLayer++; - if (curLayer >= layers.length) - { - // special case all layers - curLayer = -1; - layerName = "*"; - } - else - layerName = layers[curLayer].getName(); - // Display the layer name for a short period - systemLCD.clear(); - systemLCD.drawString(layerName, (systemLCD.getTextWidth()-layerName.length() + 1)/2, 1); - switchToLayer("SYSTEM"); - Delay.msDelay(2000); - systemLCD.clear(); - switchToLayer(layerName); - } - Delay.msDelay(100); - } - } - } - - static class RedirectStream extends PrintStream { - PrintStream orig, lcd; - - public RedirectStream(PrintStream orig, OutputStream os) { - super(os); - this.orig = orig; - } - - @Override - public void write(int x) { - super.write(x); - orig.write(x); - orig.flush(); - } - - @Override - public void write(byte[] b, int o, int l) { - super.write(b,o,l); - orig.write(b,o,l); - orig.flush(); - } - - @Override - public void close() { - super.close(); - orig.close(); - } - - @Override - public void flush() { - super.flush(); - orig.flush(); - } - } -} diff --git a/ev3classes/src/main/java/lejos/internal/ev3/package-info.java b/ev3classes/src/main/java/lejos/internal/ev3/package-info.java deleted file mode 100644 index ef09c8b..0000000 --- a/ev3classes/src/main/java/lejos/internal/ev3/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * EV3-specific implementations that are not part of the published API. - */ -package lejos.internal.ev3; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/internal/io/NativeDevice.java b/ev3classes/src/main/java/lejos/internal/io/NativeDevice.java deleted file mode 100644 index 526f74b..0000000 --- a/ev3classes/src/main/java/lejos/internal/io/NativeDevice.java +++ /dev/null @@ -1,42 +0,0 @@ -package lejos.internal.io; - -import java.io.IOError; -import com.sun.jna.Pointer; - -/** - * This class provides access from Java to Linux character devices. It is intended - * to allow access from Java to the Lego kernel modules which provide access to - * EV3 hardware features. - *

    - * TODO: Find a better way to return memory mapped data for use by Java. - * @author andy - * - */ -public class NativeDevice extends NativeFile -{ - /** - * Create a native device to provide access to the specified character device - * @param dname name of the character device - */ - public NativeDevice(String dname) - { - super(); - try { - open(dname, O_RDWR, 0); - } catch(Exception e) - { - throw new IOError(e); - } - } - - /** - * Map a portion of the device into memory and return a pointer which can be - * used to read/write the device. - * @param len number of bytes to map - * @return a pointer that can be used to access the device memory - */ - public Pointer mmap(long len) - { - return super.mmap(len, PROT_READ | PROT_WRITE, MAP_SHARED, 0); - } -} diff --git a/ev3classes/src/main/java/lejos/internal/io/NativeFile.java b/ev3classes/src/main/java/lejos/internal/io/NativeFile.java deleted file mode 100644 index 81e29df..0000000 --- a/ev3classes/src/main/java/lejos/internal/io/NativeFile.java +++ /dev/null @@ -1,244 +0,0 @@ -package lejos.internal.io; - -import com.sun.jna.Native; -import com.sun.jna.NativeLong; -import com.sun.jna.Pointer; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.Buffer; -import java.nio.channels.FileChannel; - -/** - * This class provides access to Linux files using native I/O operations. It is - * implemented using the JNA package. The class is required because certain - * operations (like ioctl) that are required by the Lego kernel module interface are - * not support by standard Java methods. In addition standard Java memory mapped - * files do not seem to function correctly when used with Linux character devices. - *

    - * Where possible standard Java classes and methods are used. JNA is used to extended - * the standard Java interface as required. - * @author andy - * - */ -public class NativeFile -{ - static final int O_ACCMODE = 0003; - static final int O_RDONLY = 00; - static final int O_WRONLY = 01; - static final int O_RDWR = 02; - static final int O_CREAT = 0100; - static final int O_EXCL = 0200; - static final int O_NOCTTY = 0400; - static final int O_TRUNC = 01000; - static final int O_APPEND = 02000; - static final int O_NONBLOCK = 04000; - static final int O_NDELAY = O_NONBLOCK; - static final int O_SYNC = 04010000; - static final int O_FSYNC = O_SYNC; - static final int O_ASYNC = 020000; - static final int PROT_READ = 1; - static final int PROT_WRITE = 2; - static final int MAP_SHARED = 1; - static final int MAP_PRIVATE = 2; - static final int MAP_FILE = 0; - - - static class Linux_C_lib_DirectMapping { - native public int fcntl(int fd, int cmd, int arg); - - native public int ioctl(int fd, int cmd, byte[] arg); - - native public int ioctl(int fd, int cmd, Pointer p); - - native public int open(String path, int flags); - - native public int close(int fd); - - - native public int write(int fd, Buffer buffer, int count); - - native public int read(int fd, Buffer buffer, int count); - - native public Pointer mmap(Pointer addr, NativeLong len, int prot, int flags, int fd, - NativeLong off); - - static { - try { - Native.register("c"); - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - - static Linux_C_lib_DirectMapping clib = new Linux_C_lib_DirectMapping(); - - int fd; - RandomAccessFile jfd; - FileChannel fc; - - protected NativeFile() - { - - } - - /** - * Create a NativeFile object and open the associated file/device - * for native access. - * @param fname the name of the file to open - * @param flags Linux style file access flags - * @param mode Linux style file access mode - * @throws FileNotFoundException - */ - public NativeFile(String fname, int flags, int mode) throws FileNotFoundException - { - open(fname, flags, mode); - } - - /** - * Open the specified file/device - * for native access. - * @param fname the name of the file to open - * @param flags Linux style file access flags - * @param mode Linux style file access mode - * @throws FileNotFoundException - */ - public void open(String fname, int flags, int mode) throws FileNotFoundException - { - fd = clib.open(fname, flags); - if (fd < 0) - throw new FileNotFoundException("File: " + fname + " errno " + Native.getLastError()); - jfd = new RandomAccessFile(fname, "rw"); - fc = jfd.getChannel(); - } - - /** - * Attempt to read the requested number of bytes from the associated file. - * @param buf location to store the read bytes - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int read(byte[] buf, int len) - { - try - { - return fc.read(ByteBuffer.wrap(buf, 0, len)); - } catch (IOException e) - { - return -1; - } - } - - /** - * Attempt to write the requested number of bytes to the associated file. - * @param buf location to store the read bytes - * @param offset the offset within buf to take data from for the write - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int write(byte[] buf, int offset, int len) - { - try - { - return fc.write(ByteBuffer.wrap(buf, offset, len)); - } catch (IOException e) - { - return -1; - } - } - - /** - * Attempt to read the requested number of byte from the associated file. - * @param buf location to store the read bytes - * @param offset offset with buf to start storing the read bytes - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int read(byte[] buf, int offset, int len) - { - try - { - return fc.read(ByteBuffer.wrap(buf, offset, len)); - } catch (IOException e) - { - return -1; - } - } - - /** - * Attempt to write the requested number of bytes to the associated file. - * @param buf location to store the read bytes - * @param len number of bytes to attempt to read - * @return number of bytes read or -1 if there is an error - */ - public int write(byte[] buf, int len) - { - try - { - return fc.write(ByteBuffer.wrap(buf, 0, len)); - } catch (IOException e) - { - return -1; - } - } - - /** - * Perform a Linux style ioctl operation on the associated file. - * @param req ioctl operation to be performed - * @param buf byte array containing the ioctl parameters if any - * @return Linux style ioctl return - */ - public int ioctl(int req, byte[] buf) - { - return clib.ioctl(fd, req, buf); - } - - /** - * Perform a Linux style ioctl operation on the associated file. - * @param req ioctl operation to be performed - * @param buf pointer to ioctl parameters - * @return Linux style ioctl return - */ - public int ioctl(int req, Pointer buf) - { - return clib.ioctl(fd, req, buf); - } - - /** - * Close the associated file - * @return Linux style return - */ - public int close() - { - try - { - fc.close(); - jfd.close(); - } catch (IOException e) - { - e.printStackTrace(); - } - return clib.close(fd); - } - - /** - * Map a portion of the associated file into memory and return a pointer - * that can be used to access that memory. - * @param len size of the region to map - * @param prot protection for the memory region - * @param flags Linux mmap flags - * @param off offset within the file for the start of the region - * @return a pointer that can be used to access the mapped data - */ - public Pointer mmap(long len, int prot, int flags, long off) - { - Pointer p = clib.mmap(new Pointer(0), new NativeLong(len), prot, flags, fd, new NativeLong(off)); - if (p == null) - return null; - return p; - } - -} diff --git a/ev3classes/src/main/java/lejos/internal/io/NativeHCI.java b/ev3classes/src/main/java/lejos/internal/io/NativeHCI.java deleted file mode 100644 index a360683..0000000 --- a/ev3classes/src/main/java/lejos/internal/io/NativeHCI.java +++ /dev/null @@ -1,203 +0,0 @@ -package lejos.internal.io; - -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import lejos.hardware.RemoteBTDevice; - -import com.sun.jna.LastErrorException; -import com.sun.jna.Memory; -import com.sun.jna.Native; -import com.sun.jna.Pointer; -import com.sun.jna.Structure; -import com.sun.jna.ptr.PointerByReference; - -public class NativeHCI { - - public static final int PSCAN = 0x8; - public static final int ISCAN = 0x10; - public static final int PISCAN = 0x18; - public static final int NOSCAN = 0; - - public static class DeviceInfo extends Structure implements Structure.ByReference { - public short dev_id; - public byte[] name = new byte[8]; - public byte[] bdaddr = new byte[6]; - public int flags; - public byte type; - public byte[]features = new byte[8]; - public int pkt_type; - public int link_policy; - public int link_mode; - public short acl_mtu; - public short acl_pkts; - public short sco_mtu; - public short sco_pkts; - public int[] stat = new int[10]; - @Override - protected List getFieldOrder() - { - // TODO Auto-generated method stub - return Arrays.asList(new String[] {"dev_id", - "name", - "bdaddr", - "flags", - "type", - "features", - "pkt_type", - "link_policy", - "link_mode", - "acl_mtu", - "acl_pkts", - "sco_mtu", - "sco_pkts", - "stat"}); - } - } - - public static class LocalVersion extends Structure implements Structure.ByReference { - public short manufacturer; - public byte hci_ver; - public short hci_rev; - public byte lmp_ver; - public short lmp_subver; - @Override - protected List getFieldOrder() - { - // TODO Auto-generated method stub - return Arrays.asList(new String[] { - "manufacturer", - "hci_ver", - "hci_rev", - "lmp_ver", - "lmp_subver"}); - } - - } - - static class LibBlue { - native public int hci_get_route(Pointer addr) throws LastErrorException; - - native public int hci_open_dev(int dev_id) throws LastErrorException; - - native public int hci_inquiry(int dev_id, int len, int num_rsp, Pointer lap, PointerByReference ii, long flags) throws LastErrorException; - - native public int hci_send_cmd(int sock, short ogf, short ocf, byte plen, Buffer param) throws LastErrorException; - - native public int hci_read_remote_name(int dd, byte[] bdaddr, int len, Buffer name, int to) throws LastErrorException; - - native public int hci_devinfo(int dev_id, DeviceInfo di) throws LastErrorException; - - native public int hci_read_local_version(int dev_id, LocalVersion lv, int to) throws LastErrorException; - - static { - try { - Native.register("bluetooth"); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - static LibBlue blue = new LibBlue(); - - public static final int AF_UNIX = 1; - public static final int SOCK_STREAM = 1; - public static final int SOCK_RAW = 3; - - public static final int PROTOCOL = 0; - - public static final int AF_BLUETOOTH = 31; - - public static final int BTPROTO_RFCOMM = 3; - public static final int BTPROTO_HCI = 1; - - public static final int SCAN_DISABLED = 0x00; - public static final int SCAN_INQUIRY = 0x01; - public static final int SCAN_PAGE = 0x02; - - public static final short OGF_HOST_CTL = 0x03; - public static final short OCF_WRITE_SCAN_ENABLE = 0x001A; - - static final int INQUIRY_INFO_SIZE = 14; - - public static final int MAX_RSP = 32; - - private int deviceId; - private int socket; - - private Pointer inquiryResults = new Memory(MAX_RSP*INQUIRY_INFO_SIZE); - - private ArrayList remoteDevices = new ArrayList(); - - private DeviceInfo deviceInfo = new DeviceInfo(); - private LocalVersion localVersion = new LocalVersion(); - - public NativeHCI() { - deviceId = blue.hci_get_route(null); - socket = blue.hci_open_dev(deviceId); - blue.hci_devinfo(deviceId, deviceInfo); - } - - public Collection hciInquiry() throws LastErrorException { - int numRsp = blue.hci_inquiry(deviceId, 8, MAX_RSP, null, new PointerByReference(inquiryResults), 0x0001); - remoteDevices.clear(); - - for(int i=0;i - * aCodeResulting Sound - * 0short beep - * 1double beep - * 2descending arpeggio - * 3ascending arpeggio - * 4long, low buzz - * - */ - public void systemSound(int aCode) throws RemoteException; - - /** - * Plays a tone, given its frequency and duration. - * @param aFrequency The frequency of the tone in Hertz (Hz). - * @param aDuration The duration of the tone, in milliseconds. - * @param aVolume The volume of the playback 100 corresponds to 100% - */ - public void playTone(int aFrequency, int aDuration, int aVolume) throws RemoteException; - - - public void playTone(int freq, int duration) throws RemoteException; - - - /** - * Play a wav file - * @param file the 8-bit PWM (WAV) sample file - * @param vol the volume percentage 0 - 100 - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file, int vol) throws RemoteException; - - - /** - * Play a wav file - * @param file the 8-bit PWM (WAV) sample file - * @return The number of milliseconds the sample will play for or < 0 if - * there is an error. - * @throws FileNotFoundException - */ - public int playSample(File file) throws RemoteException; - - /** - * Queue a series of PCM samples to play at the - * specified volume and sample rate. - * - * @param data Buffer containing the samples - * @param offset Offset of the first sample in the buffer - * @param len Number of samples to queue - * @param freq Sample rate - * @param vol playback volume - * @return Number of samples actually queued - */ - public int playSample(byte [] data, int offset, int len, int freq, int vol) throws RemoteException; - - /** - * Play a note with attack, decay, sustain and release shape. This function - * allows the playing of a more musical sounding note. It uses a set of - * supplied "instrument" parameters to define the shape of the notes - * envelope. - * @param inst Instrument definition - * @param freq The note to play (in Hz) - * @param len The duration of the note (in ms) - */ - public void playNote(int[] inst, int freq, int len) throws RemoteException; - - /** - * Set the master volume level - * @param vol 0-100 - */ - public void setVolume(int vol) throws RemoteException; - - /** - * Get the current master volume level - * @return the current master volume 0-100 - */ - public int getVolume() throws RemoteException; - - /** - * Load the current system settings associated with this class. Called - * automatically to initialize the class. May be called if it is required - * to reload any settings. - */ - public void loadSettings() throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIBattery.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIBattery.java deleted file mode 100644 index 984a257..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIBattery.java +++ /dev/null @@ -1,31 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMIBattery extends Remote { - - /** - * The NXT uses 6 batteries of 1500 mV each. - * @return Battery voltage in mV. ~9000 = full. - */ - public int getVoltageMilliVolt() throws RemoteException; - - /** - * The NXT uses 6 batteries of 1.5 V each. - * @return Battery voltage in Volt. ~9V = full. - */ - public float getVoltage() throws RemoteException; - - /** - * Return the current draw from the battery - * @return current in Amps - */ - public float getBatteryCurrent() throws RemoteException; - - /** - * return the motor current draw - * @return current in Amps - */ - public float getMotorCurrent() throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIBluetooth.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIBluetooth.java deleted file mode 100644 index c10a8e4..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIBluetooth.java +++ /dev/null @@ -1,19 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.util.Collection; - -import lejos.hardware.RemoteBTDevice; - -public interface RMIBluetooth extends Remote { - - public Collection search() throws RemoteException; - - public String getBluetoothAddress() throws RemoteException; - - public boolean getVisibility() throws RemoteException; - - public void setVisibility(boolean visible) throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIEV3.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIEV3.java deleted file mode 100644 index cad0a0d..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIEV3.java +++ /dev/null @@ -1,44 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.hardware.lcd.Font; - -public interface RMIEV3 extends Remote { - - public RMIAnalogPort openAnalogPort(String portName) throws RemoteException; - - public RMII2CPort openI2CPort(String portName) throws RemoteException; - - public RMIBattery getBattery() throws RemoteException; - - public RMIUARTPort openUARTPort(String portName) throws RemoteException; - - public RMIMotorPort openMotorPort(String portName) throws RemoteException; - - public RMISampleProvider createSampleProvider(String portName, String sensorName, String modeName) throws RemoteException; - - public RMIRegulatedMotor createRegulatedMotor(String portName, char motorType) throws RemoteException; - - public RMIAudio getAudio() throws RemoteException; - - public RMITextLCD getTextLCD() throws RemoteException; - - public RMITextLCD getTextLCD(Font f) throws RemoteException; - - public RMIGraphicsLCD getGraphicsLCD() throws RemoteException; - - public RMIWifi getWifi() throws RemoteException; - - public RMIBluetooth getBluetooth() throws RemoteException; - - public String getName() throws RemoteException; - - public RMIKey getKey(String name) throws RemoteException; - - public RMILED getLED() throws RemoteException; - - public RMIKeys getKeys() throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIGraphicsLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIGraphicsLCD.java deleted file mode 100644 index 6e05d65..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIGraphicsLCD.java +++ /dev/null @@ -1,96 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.Image; - -public interface RMIGraphicsLCD extends Remote { - - public void setPixel(int x, int y, int color) throws RemoteException; - - public int getPixel(int x, int y) throws RemoteException; - - public void drawString(String str, int x, int y, int anchor, boolean inverted) throws RemoteException; - - public void drawString(String str, int x, int y, int anchor) throws RemoteException; - - public void drawSubstring(String str, int offset, int len, - int x, int y, int anchor) throws RemoteException; - - public void drawChar(char character, int x, int y, int anchor) throws RemoteException; - - public void drawChars(char[] data, int offset, int length, - int x, int y, int anchor) throws RemoteException; - - public int getStrokeStyle() throws RemoteException; - - public void setStrokeStyle(int style) throws RemoteException; - - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, int y, int anchor, int rop) throws RemoteException; - - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int transform, int x, int y, int anchor, int rop) throws RemoteException; - - public void drawRegion(Image src, - int sx, int sy, - int w, int h, - int transform, - int x, int y, - int anchor) throws RemoteException; - - public void drawImage(Image src, int x, int y, int anchor) throws RemoteException; - - public void drawLine(int x0, int y0, int x1, int y1) throws RemoteException; - - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) throws RemoteException; - - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) throws RemoteException; - - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) throws RemoteException; - - public void drawRect(int x, int y, int width, int height) throws RemoteException; - - public void fillRect(int x, int y, int w, int h) throws RemoteException; - - public void copyArea(int sx, int sy, - int w, int h, - int x, int y, int anchor) throws RemoteException; - - public Font getFont() throws RemoteException; - - public void setFont(Font f) throws RemoteException; - - public void translate(int x, int y) throws RemoteException; - - public int getTranslateX() throws RemoteException; - - public int getTranslateY() throws RemoteException; - - public void setColor(int rgb) throws RemoteException; - - public void setColor(int red, int green, int blue) throws RemoteException; - - public void refresh() throws RemoteException; - - public void clear() throws RemoteException; - - public int getWidth() throws RemoteException; - - public int getHeight() throws RemoteException; - - public byte[] getDisplay() throws RemoteException; - - public byte[] getHWDisplay() throws RemoteException; - - public void setContrast(int contrast) throws RemoteException; - - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, int dy, int w, int h, int rop) throws RemoteException; - - 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) throws RemoteException; - - public void setAutoRefresh(boolean on) throws RemoteException; - - public int setAutoRefreshPeriod(int period) throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMII2CPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMII2CPort.java deleted file mode 100644 index 840f5b1..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMII2CPort.java +++ /dev/null @@ -1,27 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMII2CPort extends Remote { - - /** - * High level i2c interface. Perform a complete i2c transaction and return - * the results. Writes the specified data to the device and then reads the - * requested bytes from it. - * @param deviceAddress The I2C device address. - * @param writeBuf The buffer containing data to be written to the device. - * @param writeOffset The offset of the data within the write buffer - * @param writeLen The number of bytes to write. - * @param readLen The length of the read - * @return < 0 error otherwise the number of bytes read - */ - public byte[] i2cTransaction(int deviceAddress, byte[]writeBuf, - int writeOffset, int writeLen, - int readLen) throws RemoteException; - - - public void close() throws RemoteException; - - boolean setType(int type) throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIKey.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIKey.java deleted file mode 100644 index f0ac09d..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIKey.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.hardware.KeyListener; - -public interface RMIKey extends Remote { - - public static final int UP = 0; - public static final int ENTER = 1; - public static final int DOWN = 2; - public static final int RIGHT = 3; - public static final int LEFT = 4; - public static final int ESCAPE = 5; - - public int getId() throws RemoteException; - - public boolean isDown() throws RemoteException; - - public boolean isUp() throws RemoteException; - - public void waitForPress() throws RemoteException; - - public void waitForPressAndRelease() throws RemoteException; - - public void addKeyListener (KeyListener listener) throws RemoteException; - - public void simulateEvent(int event) throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIKeys.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIKeys.java deleted file mode 100644 index e59de7e..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIKeys.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMIKeys extends Remote { - - public void discardEvents() throws RemoteException; - - public int waitForAnyEvent() throws RemoteException; - - public int waitForAnyEvent(int timeout) throws RemoteException; - - public int waitForAnyPress(int timeout) throws RemoteException; - - public int waitForAnyPress() throws RemoteException; - - public int getButtons() throws RemoteException; - - public int readButtons() throws RemoteException; - - public void setKeyClickVolume(int vol) throws RemoteException; - - public int getKeyClickVolume() throws RemoteException; - - public void setKeyClickLength(int len) throws RemoteException; - - public int getKeyClickLength() throws RemoteException; - - public void setKeyClickTone(int key, int freq) throws RemoteException; - - public int getKeyClickTone(int key) throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMILCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMILCD.java deleted file mode 100644 index 5e057eb..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMILCD.java +++ /dev/null @@ -1,20 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMILCD extends Remote { - - public void drawChar(char c, int x, int y) throws RemoteException; - - public void clearDisplay() throws RemoteException; - - public void drawString(String str, int x, int y, boolean inverted) throws RemoteException; - - public void drawString(String str, int x, int y) throws RemoteException; - - public void drawInt(int i, int x, int y) throws RemoteException; - - public void drawInt(int i, int places, int x, int y) throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMILED.java b/ev3classes/src/main/java/lejos/remote/ev3/RMILED.java deleted file mode 100644 index 2f64a5c..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMILED.java +++ /dev/null @@ -1,10 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMILED extends Remote { - - public void setPattern(int pattern) throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIMenu.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIMenu.java deleted file mode 100644 index 3212b2b..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIMenu.java +++ /dev/null @@ -1,52 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMIMenu extends Remote { - - public void runProgram(String programName) throws RemoteException; - - public void debugProgram(String programName) throws RemoteException; - - public void runSample(String programName) throws RemoteException; - - public void stopProgram() throws RemoteException; - - public boolean deleteFile(String fileName) throws RemoteException; - - public long getFileSize(String fileName) throws RemoteException; - - public String[] getProgramNames() throws RemoteException; - - public String[] getSampleNames() throws RemoteException; - - public boolean uploadFile(String fileName, byte[] contents) throws RemoteException; - - public byte[] fetchFile(String fileName) throws RemoteException; - - public String getSetting(String setting) throws RemoteException; - - public void setSetting(String setting, String value) throws RemoteException; - - public void deleteAllPrograms() throws RemoteException; - - public String getVersion() throws RemoteException; - - public String getMenuVersion() throws RemoteException; - - public String getName() throws RemoteException; - - public void setName(String name) throws RemoteException; - - public void configureWifi(String ssid, String pwd) throws RemoteException; - - public String getExecutingProgramName() throws RemoteException; - - public void shutdown() throws RemoteException; - - public void suspend() throws RemoteException; - - public void resume() throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIMotorPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIMotorPort.java deleted file mode 100644 index 9571807..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIMotorPort.java +++ /dev/null @@ -1,37 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.hardware.port.BasicMotorPort; - -public interface RMIMotorPort extends Remote { - - /** - * Low-level method to control a motor. - * - * @param power power from 0-100 - * @param mode defined in BasicMotorPort. 1=forward, 2=backward, 3=stop, 4=float. - * @see BasicMotorPort#FORWARD - * @see BasicMotorPort#BACKWARD - * @see BasicMotorPort#FLOAT - * @see BasicMotorPort#STOP - */ - public void controlMotor(int power, int mode) throws RemoteException; - - - /** - * returns tachometer count - */ - public int getTachoCount() throws RemoteException; - - /** - *resets the tachometer count to 0; - */ - public void resetTachoCount() throws RemoteException; - - public void setPWMMode(int mode) throws RemoteException; - - public void close() throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRegulatedMotor.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRegulatedMotor.java deleted file mode 100644 index c2435ea..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRegulatedMotor.java +++ /dev/null @@ -1,154 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.robotics.RegulatedMotorListener; - -public interface RMIRegulatedMotor extends Remote { - - /** - * Adds a listener object that will be notified when rotation has started or stopped - * @param listener - */ - //TODO method name sounds like listener is added to some list. - // javadoc and method name should be changed such that they indicate that only one listener is supported. - // suggested method name: setListener(...) - public void addListener(RegulatedMotorListener listener) throws RemoteException; - - /** - * Removes the RegulatedMotorListener from this class. - * @return The RegulatedMotorListener that was removed, if any. Null if none existed. - */ - public RegulatedMotorListener removeListener() throws RemoteException; - - /** - * Causes motor to stop, pretty much - * instantaneously. In other words, the - * motor doesn't just stop; it will resist - * any further motion. - * Cancels any rotate() orders in progress - * @param immediateReturn if true do not wait for the motor to actually stop - */ - public void stop(boolean immediateReturn) throws RemoteException; - - /** - * Set the motor into float mode. This will stop the motor without braking - * and the position of the motor will not be maintained. - * @param immediateReturn If true do not wait for the motor to actually stop - */ - public void flt(boolean immediateReturn) throws RemoteException; - - /** - * Wait until the current movement operation is complete (this can include - * the motor stalling). - */ - public void waitComplete() throws RemoteException; - - - /** - * causes motor to rotate through angle;
    - * iff immediateReturn is true, method returns immediately and the motor stops by itself
    - * If any motor method is called before the limit is reached, the rotation is canceled. - * When the angle is reached, the method isMoving() returns false;
    - * - * @param angle through which the motor will rotate - * @param immediateReturn iff true, method returns immediately, thus allowing monitoring of sensors in the calling thread. - * - * @see lejos.robotics.RegulatedMotor#rotate(int, boolean) - */ - void rotate(int angle, boolean immediateReturn) throws RemoteException; - - /** - * Causes motor to rotate by a specified angle. The resulting tachometer count should be within +- 2 degrees on the NXT. - * This method does not return until the rotation is completed. - * - * @param angle by which the motor will rotate. - * - */ - void rotate(int angle) throws RemoteException; - - - /** - * Causes motor to rotate to limitAngle;
    - * Then getTachoCount should be within +- 2 degrees of the limit angle when the method returns - * @param limitAngle to which the motor will rotate, and then stop (in degrees). Includes any positive or negative int, even values > 360. - */ - public void rotateTo(int limitAngle) throws RemoteException; - - /** - * causes motor to rotate to limitAngle;
    - * if immediateReturn is true, method returns immediately and the motor stops by itself
    - * and getTachoCount should be within +- 2 degrees if the limit angle - * If any motor method is called before the limit is reached, the rotation is canceled. - * When the angle is reached, the method isMoving() returns false;
    - * @param limitAngle to which the motor will rotate, and then stop (in degrees). Includes any positive or negative int, even values > 360. - * @param immediateReturn iff true, method returns immediately, thus allowing monitoring of sensors in the calling thread. - */ - public void rotateTo(int limitAngle,boolean immediateReturn) throws RemoteException; - - /** - * Return the limit angle (if any) - * @return the current limit angle - */ - public int getLimitAngle() throws RemoteException; - - /** - * Set motor speed. As a rule of thumb 100 degrees per second are possible for each volt on an NXT motor. Therefore, - * disposable alkaline batteries can achieve a top speed of 900 deg/sec, while a rechargable lithium battery pack can achieve - * 740 deg/sec. - * - * @param speed in degrees per second. - */ - void setSpeed(int speed) throws RemoteException; - - /** - * Returns the current motor speed. - * - * @return motor speed in degrees per second - */ - int getSpeed() throws RemoteException; - - /** - * Returns the maximim speed of the motor. - * - * @return the maximum speed of the Motor in degrees per second. - */ - float getMaxSpeed() throws RemoteException; - - /** - * returns true if motor is stalled - * @return true if stalled - */ - boolean isStalled() throws RemoteException; - - /** - * Set the parameters for detecting a stalled motor. A motor will be recognized as - * stalled if the movement error (the amount the motor lags the regulated position) - * is greater than error for a period longer than time. - * - * @param error The error threshold - * @param time The time that the error threshold needs to be exceeded for. - */ - void setStallThreshold(int error, int time) throws RemoteException; - - /** - * Set the required rate of acceleration degrees/s/s - * @param acceleration - */ - void setAcceleration(int acceleration) throws RemoteException; - - void close() throws RemoteException; - - void forward() throws RemoteException; - - void backward() throws RemoteException; - - void resetTachoCount() throws RemoteException; - - int getTachoCount() throws RemoteException; - - boolean isMoving() throws RemoteException; - -} - diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAnalogPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAnalogPort.java deleted file mode 100644 index abcb11b..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAnalogPort.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.remote.ev3; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.AnalogPort; -import lejos.remote.ev3.RMIAnalogPort; - -public class RMIRemoteAnalogPort extends UnicastRemoteObject implements RMIAnalogPort { - private AnalogPort port; - - private static final long serialVersionUID = 3049365457299818710L; - - protected RMIRemoteAnalogPort(String portName) throws RemoteException { - super(0); - port = LocalEV3.get().getPort(portName).open(AnalogPort.class); - } - - @Override - public float getPin6() throws RemoteException { - return port.getPin6(); - } - - @Override - public float getPin1() throws RemoteException { - return port.getPin1(); - } - - @Override - public void close() throws RemoteException { - port.close(); - } - - @Override - public boolean setPinMode(int mode) throws RemoteException { - return port.setPinMode(mode); - } - - @Override - public void getFloats(float[] vals, int offset, int length) - throws RemoteException - { - port.getFloats(vals, offset, length); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAudio.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAudio.java deleted file mode 100644 index f25cfab..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteAudio.java +++ /dev/null @@ -1,68 +0,0 @@ -package lejos.remote.ev3; - -import java.io.File; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.Audio; -import lejos.hardware.ev3.LocalEV3; - -public class RMIRemoteAudio extends UnicastRemoteObject implements RMIAudio { - private Audio audio = LocalEV3.get().getAudio(); - - private static final long serialVersionUID = -1570513073865401851L; - - protected RMIRemoteAudio() throws RemoteException { - super(0); - } - - @Override - public void systemSound(int aCode) throws RemoteException { - audio.systemSound(aCode); - } - - @Override - public void playTone(int aFrequency, int aDuration, int aVolume) throws RemoteException { - audio.playTone(aFrequency, aDuration, aVolume); - } - - @Override - public void playTone(int freq, int duration) throws RemoteException { - audio.playTone(freq, duration); - } - - @Override - public int playSample(File file, int vol) throws RemoteException { - return audio.playSample(file, vol); - } - - @Override - public int playSample(File file) throws RemoteException { - return audio.playSample(file); - } - - @Override - public int playSample(byte[] data, int offset, int len, int freq, int vol) throws RemoteException{ - return audio.playSample(data, offset, len, freq, vol); - } - - @Override - public void playNote(int[] inst, int freq, int len) throws RemoteException { - audio.playNote(inst, freq, len); - } - - @Override - public void setVolume(int vol) throws RemoteException { - audio.setVolume(vol); - } - - @Override - public int getVolume() throws RemoteException{ - return audio.getVolume(); - } - - @Override - public void loadSettings() throws RemoteException { - audio.loadSettings(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBattery.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBattery.java deleted file mode 100644 index aab5983..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBattery.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.remote.ev3; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.remote.ev3.RMIBattery; - -public class RMIRemoteBattery extends UnicastRemoteObject implements RMIBattery { - - protected RMIRemoteBattery() throws RemoteException { - super(0); - } - - @Override - public int getVoltageMilliVolt() throws RemoteException { - return LocalEV3.get().getPower().getVoltageMilliVolt(); - } - - @Override - public float getVoltage() throws RemoteException { - return LocalEV3.get().getPower().getVoltage(); - } - - @Override - public float getBatteryCurrent() throws RemoteException { - return LocalEV3.get().getPower().getBatteryCurrent(); - } - - @Override - public float getMotorCurrent() throws RemoteException { - return LocalEV3.get().getPower().getMotorCurrent(); - } - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBluetooth.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBluetooth.java deleted file mode 100644 index dc742b1..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteBluetooth.java +++ /dev/null @@ -1,58 +0,0 @@ -package lejos.remote.ev3; - -import java.io.IOException; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import java.util.Collection; - -import lejos.hardware.Bluetooth; -import lejos.hardware.BluetoothException; -import lejos.hardware.LocalBTDevice; -import lejos.hardware.RemoteBTDevice; - -public class RMIRemoteBluetooth extends UnicastRemoteObject implements RMIBluetooth { - private static final long serialVersionUID = 6508261990932121690L; - private LocalBTDevice blue = Bluetooth.getLocalDevice(); - - protected RMIRemoteBluetooth() throws RemoteException { - super(0); - } - - @Override - public Collection search() throws RemoteException { - try { - return blue.search(); - } catch (BluetoothException e) { - throw new RemoteException(e.getMessage()); - } - } - - @Override - public String getBluetoothAddress() throws RemoteException { - try { - return blue.getBluetoothAddress(); - } catch (BluetoothException e) { - throw new RemoteException(e.getMessage()); - } - } - - @Override - public boolean getVisibility() throws RemoteException { - try { - return blue.getVisibility(); - } catch (BluetoothException e) { - throw new RemoteException(e.getMessage()); - } - } - - @Override - public void setVisibility(boolean visible) throws RemoteException { - try { - blue.setVisibility(visible); - } catch (BluetoothException e) { - throw new RemoteException(e.getMessage()); - } - } - - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteEV3.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteEV3.java deleted file mode 100644 index 2306229..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteEV3.java +++ /dev/null @@ -1,114 +0,0 @@ -package lejos.remote.ev3; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.lcd.Font; -import lejos.internal.ev3.EV3Key; -import lejos.remote.ev3.RMIAnalogPort; -import lejos.remote.ev3.RMIBattery; -import lejos.remote.ev3.RMIEV3; -import lejos.remote.ev3.RMII2CPort; -import lejos.remote.ev3.RMIMotorPort; -import lejos.remote.ev3.RMIUARTPort; - - -public class RMIRemoteEV3 extends UnicastRemoteObject implements RMIEV3 { - - private static final long serialVersionUID = -6637513883001761328L; - - public RMIRemoteEV3() throws RemoteException { - super(0); - } - - @Override - public RMIBattery getBattery() throws RemoteException { - return new RMIRemoteBattery(); - } - - @Override - public RMIAnalogPort openAnalogPort(String portName) throws RemoteException { - return new RMIRemoteAnalogPort(portName); - } - - @Override - public RMII2CPort openI2CPort(String portName) throws RemoteException { - return new RMIRemoteI2CPort(portName); - } - - @Override - public RMIUARTPort openUARTPort(String portName) throws RemoteException { - return new RMIRemoteUARTPort(portName); - } - - @Override - public RMIMotorPort openMotorPort(String portName) throws RemoteException { - return new RMIRemoteMotorPort(portName); - } - - @Override - public RMISampleProvider createSampleProvider(String portName, - String sensorName, String modeName) throws RemoteException { - return new RMIRemoteSampleProvider(portName, sensorName, modeName); - } - - @Override - public RMIRegulatedMotor createRegulatedMotor(String portName, char motorType) - throws RemoteException { - return new RMIRemoteRegulatedMotor(portName, motorType); - } - - @Override - public RMIWifi getWifi() throws RemoteException { - return new RMIRemoteWifi(); - } - - @Override - public RMIBluetooth getBluetooth() throws RemoteException { - return new RMIRemoteBluetooth(); - } - - @Override - public RMITextLCD getTextLCD() throws RemoteException { - return new RMIRemoteTextLCD(); - } - - @Override - public RMIAudio getAudio() throws RemoteException { - return new RMIRemoteAudio(); - } - - @Override - public RMIGraphicsLCD getGraphicsLCD() throws RemoteException { - return new RMIRemoteGraphicsLCD(); - } - - @Override - public RMITextLCD getTextLCD(Font f) throws RemoteException { - RMIRemoteTextLCD lcd = new RMIRemoteTextLCD(); - lcd.setFont(f); - return lcd; - } - - @Override - public String getName() throws RemoteException { - return LocalEV3.get().getName(); - } - - @Override - public RMIKey getKey(String name) throws RemoteException { - RMIRemoteKey key = new RMIRemoteKey(); - key.setId(name); - return key; - } - - @Override - public RMILED getLED() throws RemoteException { - return new RMIRemoteLED(); - } - - @Override - public RMIKeys getKeys() throws RemoteException { - return new RMIRemoteKeys(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteGraphicsLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteGraphicsLCD.java deleted file mode 100644 index 1c6fc6d..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteGraphicsLCD.java +++ /dev/null @@ -1,227 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.Image; - -public class RMIRemoteGraphicsLCD extends UnicastRemoteObject implements RMIGraphicsLCD { - - private static final long serialVersionUID = 1561883712422890550L; - private GraphicsLCD g = LocalEV3.get().getGraphicsLCD(); - - protected RMIRemoteGraphicsLCD() throws RemoteException { - super(0); - } - - @Override - public void setPixel(int x, int y, int color) throws RemoteException { - g.setPixel(x, y, color); - } - - @Override - public int getPixel(int x, int y) throws RemoteException { - return g.getPixel(x, y); - } - - @Override - public void drawString(String str, int x, int y, int anchor, - boolean inverted) throws RemoteException { - g.drawString(str, x, y, anchor, inverted); - } - - @Override - public void drawString(String str, int x, int y, int anchor) - throws RemoteException { - g.drawString(str, x, y, anchor); - } - - @Override - public void drawSubstring(String str, int offset, int len, int x, int y, - int anchor) throws RemoteException { - g.drawSubstring(str, offset, len, x, y, anchor); - } - - @Override - public void drawChar(char character, int x, int y, int anchor) - throws RemoteException { - g.drawChar(character, x, y, anchor); - } - - @Override - public void drawChars(char[] data, int offset, int length, int x, int y, - int anchor) throws RemoteException { - g.drawChars(data, offset, length, x, y, anchor); - } - - @Override - public int getStrokeStyle() throws RemoteException { - return g.getStrokeStyle(); - } - - @Override - public void setStrokeStyle(int style) throws RemoteException { - g.setStrokeStyle(style); - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, - int y, int anchor, int rop) throws RemoteException { - g.drawRegionRop(src, sx, sy, w, h, x, y, anchor, rop); - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor, int rop) - throws RemoteException { - g.drawRegionRop(src, sx, sy, w, h, transform, x, y, anchor, rop); - } - - @Override - public void drawRegion(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor) throws RemoteException { - g.drawRegion(src, sx, sy, w, h, transform, x, y, anchor); - } - - @Override - public void drawImage(Image src, int x, int y, int anchor) - throws RemoteException { - g.drawImage(src, x, y, anchor); - } - - @Override - public void drawLine(int x0, int y0, int x1, int y1) throws RemoteException { - g.drawLine(x0, y0, x1, y1); - } - - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) throws RemoteException { - g.drawArc(x, y, width, height, startAngle, arcAngle); - } - - @Override - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) throws RemoteException { - g.fillArc(x, y, width, height, startAngle, arcAngle); - } - - @Override - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) throws RemoteException { - g.drawRoundRect(x, y, width, height, arcWidth, arcHeight); - } - - @Override - public void drawRect(int x, int y, int width, int height) - throws RemoteException { - g.drawRect(x, y, width, height); - } - - @Override - public void fillRect(int x, int y, int w, int h) throws RemoteException { - g.fillRect(x, y, w, h); - } - - @Override - public void copyArea(int sx, int sy, int w, int h, int x, int y, int anchor) - throws RemoteException { - g.copyArea(sx, sy, w, h, x, y, anchor); - } - - @Override - public Font getFont() throws RemoteException { - return g.getFont(); - } - - @Override - public void setFont(Font f) throws RemoteException { - g.setFont(f); - } - - @Override - public void translate(int x, int y) throws RemoteException { - g.translate(x, y); - } - - @Override - public int getTranslateX() throws RemoteException { - return g.getTranslateX(); - } - - @Override - public int getTranslateY() throws RemoteException { - return g.getTranslateY(); - } - - @Override - public void setColor(int rgb) throws RemoteException { - g.setColor(rgb); - } - - @Override - public void setColor(int red, int green, int blue) throws RemoteException { - g.setColor(red, green, blue); - } - - @Override - public void refresh() throws RemoteException { - g.refresh(); - } - - @Override - public void clear() throws RemoteException { - g.clear(); - } - - @Override - public int getWidth() throws RemoteException { - return g.getWidth(); - } - - @Override - public int getHeight() throws RemoteException { - return g.getHeight(); - } - - @Override - public byte[] getDisplay() throws RemoteException { - return g.getDisplay(); - } - - @Override - public byte[] getHWDisplay() throws RemoteException { - return g.getHWDisplay(); - } - - @Override - public void setContrast(int contrast) throws RemoteException { - g.setContrast(contrast); - } - - @Override - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, - int dy, int w, int h, int rop) throws RemoteException { - g.bitBlt(src, sw, sh, sx, sy, dx, dy, w, h, rop); - } - - @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) - throws RemoteException { - g.bitBlt(src, sw, sh, sx, sy, dst, dw, dh, dx, dy, w, h, rop); - } - - @Override - public void setAutoRefresh(boolean on) throws RemoteException { - g.setAutoRefresh(on); - } - - @Override - public int setAutoRefreshPeriod(int period) throws RemoteException { - return g.setAutoRefreshPeriod(period); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteI2CPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteI2CPort.java deleted file mode 100644 index dfd7bdf..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteI2CPort.java +++ /dev/null @@ -1,37 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.I2CPort; -import lejos.remote.ev3.RMII2CPort; - -public class RMIRemoteI2CPort extends UnicastRemoteObject implements RMII2CPort { - private I2CPort port; - - private static final long serialVersionUID = 3049365457299818710L; - - protected RMIRemoteI2CPort(String portName) throws RemoteException { - super(0); - port = LocalEV3.get().getPort(portName).open(I2CPort.class); - } - - @Override - public void close() { - port.close(); - } - - @Override - public byte[] i2cTransaction(int deviceAddress, byte[] writeBuf, - int writeOffset, int writeLen, int readLen) throws RemoteException { - byte[] readBuf = new byte[readLen]; - port.i2cTransaction(deviceAddress, writeBuf, writeOffset, writeLen, readBuf, 0, readLen); - return readBuf; - } - - @Override - public boolean setType(int type) throws RemoteException { - return port.setType(type); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKey.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKey.java deleted file mode 100644 index 07dafe2..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKey.java +++ /dev/null @@ -1,57 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.Button; -import lejos.hardware.Key; -import lejos.hardware.KeyListener; -import lejos.hardware.ev3.LocalEV3; - -public class RMIRemoteKey extends UnicastRemoteObject implements RMIKey { - private Key key; - private static final long serialVersionUID = -752148808854653746L; - - protected RMIRemoteKey() throws RemoteException { - super(0); - } - - @Override - public int getId() throws RemoteException { - return key.getId(); - } - - @Override - public boolean isDown() throws RemoteException { - return key.isDown(); - } - - @Override - public boolean isUp() throws RemoteException { - return key.isUp(); - } - - @Override - public void waitForPress() throws RemoteException { - key.waitForPress(); - } - - @Override - public void waitForPressAndRelease() throws RemoteException { - key.waitForPressAndRelease(); - } - - @Override - public void addKeyListener(KeyListener listener) throws RemoteException { - key.addKeyListener(listener); - } - - @Override - public void simulateEvent(int event) throws RemoteException { - key.simulateEvent(event); - } - - public void setId(String name) { - key = LocalEV3.get().getKey(name); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKeys.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKeys.java deleted file mode 100644 index bec2d3b..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteKeys.java +++ /dev/null @@ -1,81 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.Keys; -import lejos.hardware.ev3.LocalEV3; - -public class RMIRemoteKeys extends UnicastRemoteObject implements RMIKeys { - private static final long serialVersionUID = -7696209202724226195L; - private Keys keys = LocalEV3.get().getKeys(); - - protected RMIRemoteKeys() throws RemoteException { - super(0); - } - - @Override - public void discardEvents() throws RemoteException { - keys.discardEvents(); - } - - @Override - public int waitForAnyEvent() throws RemoteException { - return keys.waitForAnyEvent(); - } - - @Override - public int waitForAnyEvent(int timeout) throws RemoteException { - return keys.waitForAnyEvent(timeout); - } - - @Override - public int waitForAnyPress(int timeout) throws RemoteException { - return keys.waitForAnyPress(timeout); - } - - @Override - public int waitForAnyPress() throws RemoteException { - return keys.waitForAnyPress(); - } - - @Override - public int getButtons() throws RemoteException { - return keys.getButtons(); - } - - @Override - public int readButtons() throws RemoteException { - return keys.readButtons(); - } - - @Override - public void setKeyClickVolume(int vol) throws RemoteException { - keys.setKeyClickVolume(vol); - } - - @Override - public int getKeyClickVolume() throws RemoteException { - return keys.getKeyClickVolume(); - } - - @Override - public void setKeyClickLength(int len) throws RemoteException { - keys.setKeyClickLength(len); - } - - @Override - public int getKeyClickLength() throws RemoteException { - return keys.getKeyClickLength(); - } - - @Override - public void setKeyClickTone(int key, int freq) throws RemoteException { - keys.setKeyClickTone(key, freq); - } - - @Override - public int getKeyClickTone(int key) throws RemoteException { - return keys.getKeyClickTone(key); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLCD.java deleted file mode 100644 index 788000f..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLCD.java +++ /dev/null @@ -1,44 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.lcd.LCD; - -public class RMIRemoteLCD extends UnicastRemoteObject implements RMILCD { - private static final long serialVersionUID = 2378483122054140698L; - - protected RMIRemoteLCD() throws RemoteException { - super(0); - } - - @Override - public void drawChar(char c, int x, int y) throws RemoteException { - LCD.drawChar(c, x, y); - } - - @Override - public void clearDisplay() throws RemoteException { - LCD.clearDisplay(); - } - - @Override - public void drawString(String str, int x, int y, boolean inverted) { - LCD.drawString(str, x, y, inverted); - } - - @Override - public void drawString(String str, int x, int y) throws RemoteException { - LCD.drawString(str, x, y); - } - - @Override - public void drawInt(int i, int x, int y) throws RemoteException { - LCD.drawInt(i, x, y); - } - - @Override - public void drawInt(int i, int places, int x, int y) throws RemoteException { - LCD.drawInt(i, places, x, y); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLED.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLED.java deleted file mode 100644 index a07a080..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteLED.java +++ /dev/null @@ -1,21 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.LED; -import lejos.hardware.ev3.LocalEV3; - -public class RMIRemoteLED extends UnicastRemoteObject implements RMILED { - private static final long serialVersionUID = -660643720408840563L; - private LED led = LocalEV3.get().getLED(); - - protected RMIRemoteLED() throws RemoteException { - super(0); - } - - @Override - public void setPattern(int pattern) throws RemoteException { - led.setPattern(pattern); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteMotorPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteMotorPort.java deleted file mode 100644 index ea7b56f..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteMotorPort.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.TachoMotorPort; -import lejos.remote.ev3.RMIMotorPort; - -public class RMIRemoteMotorPort extends UnicastRemoteObject implements RMIMotorPort { - - private static final long serialVersionUID = -5729213618672262271L; - private TachoMotorPort port; - - protected RMIRemoteMotorPort(String portName) throws RemoteException { - super(0); - port = LocalEV3.get().getPort(portName).open(TachoMotorPort.class); - } - - @Override - public void controlMotor(int power, int mode) throws RemoteException { - System.out.println("Control mode, power: " + power + ", mode: " + mode); - port.controlMotor(power, mode); - } - - @Override - public int getTachoCount() throws RemoteException { - return port.getTachoCount(); - } - - @Override - public void resetTachoCount() throws RemoteException { - port.resetTachoCount(); - } - - @Override - public void close() throws RemoteException { - port.close(); - } - - @Override - public void setPWMMode(int mode) throws RemoteException { - port.setPWMMode(mode); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteRegulatedMotor.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteRegulatedMotor.java deleted file mode 100644 index f4fc60b..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteRegulatedMotor.java +++ /dev/null @@ -1,151 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.motor.NXTRegulatedMotor; -import lejos.hardware.motor.EV3LargeRegulatedMotor; -import lejos.hardware.motor.EV3MediumRegulatedMotor; -import lejos.hardware.motor.MindsensorsGlideWheelMRegulatedMotor; -import lejos.hardware.port.Port; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; - -public class RMIRemoteRegulatedMotor extends UnicastRemoteObject implements RMIRegulatedMotor { - private static final long serialVersionUID = 224060987071610845L; - private RegulatedMotor motor; - - protected RMIRemoteRegulatedMotor(String portName, char motorType) throws RemoteException { - super(0); - Port p = LocalEV3.get().getPort(portName); - switch (motorType) { - case 'N': - motor = new NXTRegulatedMotor(p); - break; - case 'L': - motor = new EV3LargeRegulatedMotor(p); - break; - case 'M': - motor = new EV3MediumRegulatedMotor(p); - break; - case 'G': - motor = new MindsensorsGlideWheelMRegulatedMotor(p); - } - } - - @Override - public void addListener(RegulatedMotorListener listener) - throws RemoteException { - motor.addListener(listener); - } - - @Override - public RegulatedMotorListener removeListener() throws RemoteException { - return motor.removeListener(); - } - - @Override - public void stop(boolean immediateReturn) throws RemoteException { - motor.stop(immediateReturn); - } - - @Override - public void flt(boolean immediateReturn) throws RemoteException { - motor.flt(immediateReturn); - } - - @Override - public void waitComplete() throws RemoteException { - motor.waitComplete(); - } - - @Override - public void rotate(int angle, boolean immediateReturn) - throws RemoteException { - motor.rotate(angle, immediateReturn); - } - - @Override - public void rotate(int angle) throws RemoteException { - motor.rotate(angle); - } - - @Override - public void rotateTo(int limitAngle) throws RemoteException { - motor.rotateTo(limitAngle); - } - - @Override - public void rotateTo(int limitAngle, boolean immediateReturn) - throws RemoteException { - motor.rotateTo(limitAngle, immediateReturn); - } - - @Override - public int getLimitAngle() throws RemoteException { - return motor.getLimitAngle(); - } - - @Override - public void setSpeed(int speed) throws RemoteException { - motor.setSpeed(speed); - } - - @Override - public int getSpeed() throws RemoteException { - return motor.getSpeed(); - } - - @Override - public float getMaxSpeed() throws RemoteException { - return motor.getMaxSpeed(); - } - - @Override - public boolean isStalled() throws RemoteException { - return motor.isStalled(); - } - - @Override - public void setStallThreshold(int error, int time) throws RemoteException { - motor.setStallThreshold(error, time); - } - - @Override - public void setAcceleration(int acceleration) throws RemoteException { - motor.setAcceleration(acceleration); - } - - @Override - public void close() throws RemoteException { - motor.close(); - } - - @Override - public void forward() throws RemoteException { - motor.forward(); - } - - @Override - public void backward() throws RemoteException { - motor.backward(); - } - - @Override - public void resetTachoCount() throws RemoteException { - motor.resetTachoCount(); - } - - @Override - public int getTachoCount() throws RemoteException { - return motor.getTachoCount(); - } - - @Override - public boolean isMoving() throws RemoteException { - return motor.isMoving(); - } -} - diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteSampleProvider.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteSampleProvider.java deleted file mode 100644 index f6c95d2..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteSampleProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -package lejos.remote.ev3; - -import java.lang.reflect.Constructor; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.DeviceException; -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.Port; -import lejos.hardware.sensor.BaseSensor; -import lejos.robotics.SampleProvider; - -public class RMIRemoteSampleProvider extends UnicastRemoteObject implements RMISampleProvider { - - private static final long serialVersionUID = -8432755905878519147L; - private SampleProvider provider; - private BaseSensor sensor; - private int sampleSize; - - protected RMIRemoteSampleProvider(String portName, String sensorName, String modeName) throws RemoteException { - super(0); - try { - Class c = Class.forName(sensorName); - Class[] params = new Class[1]; - params[0] = Port.class; - Constructor con = c.getConstructor(params); - Object[] args = new Object[1]; - args[0] = LocalEV3.get().getPort(portName); - sensor = (BaseSensor) con.newInstance(args); - if (modeName == null) provider = (SampleProvider) sensor; - else provider = sensor.getMode(modeName); - sampleSize = provider.sampleSize(); - } catch (Exception e) { - if (sensor != null) sensor.close(); - throw new DeviceException("Failed to create sample provider", e); - } - } - - @Override - public float[] fetchSample() throws RemoteException { - float[] sample = new float[sampleSize]; - provider.fetchSample(sample, 0); - return sample; - } - - @Override - public void close() throws RemoteException { - if (sensor != null) sensor.close(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteTextLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteTextLCD.java deleted file mode 100644 index dff8254..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteTextLCD.java +++ /dev/null @@ -1,137 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.TextLCD; - -public class RMIRemoteTextLCD extends UnicastRemoteObject implements RMITextLCD { - - private static final long serialVersionUID = -7900852313387010501L; - private TextLCD lcd = LocalEV3.get().getTextLCD(); - - protected RMIRemoteTextLCD() throws RemoteException { - super(0); - } - - public void setFont(Font f) { - lcd = LocalEV3.get().getTextLCD(f); - } - - @Override - public void refresh() throws RemoteException { - lcd.refresh(); - } - - @Override - public void clear() throws RemoteException { - lcd.clear(); - } - - @Override - public int getWidth() throws RemoteException { - return lcd.getWidth(); - } - - @Override - public int getHeight() throws RemoteException { - return lcd.getHeight(); - } - - @Override - public byte[] getDisplay() throws RemoteException { - return lcd.getDisplay(); - } - - @Override - public byte[] getHWDisplay() throws RemoteException { - return lcd.getHWDisplay(); - } - - @Override - public void setContrast(int contrast) throws RemoteException { - lcd.setContrast(contrast); - } - - @Override - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, - int dy, int w, int h, int rop) throws RemoteException { - lcd.bitBlt(src, sw, sh, sx, sy, dx, dy, w, h, rop); - } - - @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) - throws RemoteException { - lcd.bitBlt(src, sw, sh, sx, sy, dst, dw, dh, dx, dy, w, h, rop); - } - - @Override - public void setAutoRefresh(boolean on) throws RemoteException { - lcd.setAutoRefresh(on); - } - - @Override - public int setAutoRefreshPeriod(int period) throws RemoteException { - return lcd.setAutoRefreshPeriod(period); - } - - @Override - public void drawChar(char c, int x, int y) throws RemoteException { - lcd.drawChar(c, x, y); - } - - @Override - public void drawString(String str, int x, int y, boolean inverted) - throws RemoteException { - lcd.drawString(str, x, y, inverted); - } - - @Override - public void drawString(String str, int x, int y) throws RemoteException { - lcd.drawString(str, x, y); - } - - @Override - public void drawInt(int i, int x, int y) throws RemoteException { - lcd.drawInt(i, x, y); - } - - @Override - public void drawInt(int i, int places, int x, int y) throws RemoteException { - lcd.drawInt(i, places, x, y); - } - - @Override - public void clear(int x, int y, int n) throws RemoteException { - lcd.clear(x, y, n); - - } - - @Override - public void clear(int y) throws RemoteException { - lcd.clear(y); - } - - @Override - public void scroll() throws RemoteException { - lcd.scroll(); - } - - @Override - public Font getFont() throws RemoteException { - return lcd.getFont(); - } - - @Override - public int getTextWidth() throws RemoteException { - return lcd.getTextWidth(); - } - - @Override - public int getTextHeight() throws RemoteException { - return lcd.getTextHeight(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteUARTPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteUARTPort.java deleted file mode 100644 index b0e3cb1..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteUARTPort.java +++ /dev/null @@ -1,98 +0,0 @@ -package lejos.remote.ev3; -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import lejos.hardware.ev3.LocalEV3; -import lejos.hardware.port.UARTPort; -import lejos.remote.ev3.RMIUARTPort; - - -public class RMIRemoteUARTPort extends UnicastRemoteObject implements RMIUARTPort { - private UARTPort port; - - private static final long serialVersionUID = 6528817103650932337L; - - protected RMIRemoteUARTPort(String portName) throws RemoteException { - super(0); - port = LocalEV3.get().getPort(portName).open(UARTPort.class); - } - - @Override - public byte getByte() throws RemoteException { - return port.getByte(); - } - - @Override - public void getBytes(byte[] vals, int offset, int len) - throws RemoteException { - port.getBytes(vals, offset, len); - } - - @Override - public int getShort() throws RemoteException { - return port.getShort(); - } - - @Override - public void getShorts(short[] vals, int offset, int len) - throws RemoteException { - port.getShorts(vals, offset, len); - } - - @Override - public String getModeName(int mode) throws RemoteException { - return port.getModeName(mode); - } - - @Override - public String toStringValue() throws RemoteException { - return port.toString(); - } - - @Override - public boolean initialiseSensor(int mode) throws RemoteException { - return port.initialiseSensor(mode); - } - - @Override - public void resetSensor() throws RemoteException { - port.resetSensor(); - } - - @Override - public void close() throws RemoteException { - port.close(); - } - - @Override - public boolean setMode(int mode) throws RemoteException { - return port.setMode(mode); - } - - @Override - public int rawRead(byte[] buffer, int offset, int len) - throws RemoteException - { - return port.rawRead(buffer, offset, len); - } - - @Override - public int rawWrite(byte[] buffer, int offset, int len) - throws RemoteException - { - return port.rawWrite(buffer, offset, len); - } - - @Override - public void setBitRate(int bitRate) throws RemoteException - { - port.setBitRate(bitRate); - } - - @Override - public int write(byte[] buffer, int offset, int len) - { - return port.write(buffer, offset, len); - - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteWifi.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteWifi.java deleted file mode 100644 index 11f76a0..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIRemoteWifi.java +++ /dev/null @@ -1,25 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; -import lejos.hardware.LocalWifiDevice; -import lejos.hardware.Wifi; - -public class RMIRemoteWifi extends UnicastRemoteObject implements RMIWifi { - private static final long serialVersionUID = -3707578706658225092L; - private LocalWifiDevice wifi = Wifi.getLocalDevice("wlan0"); - - protected RMIRemoteWifi() throws RemoteException { - super(0); - } - - @Override - public String[] getAccessPointNames() throws RemoteException { - return wifi.getAccessPointNames(); - } - - @Override - public String getAccessPoint() throws RemoteException { - return wifi.getAccessPoint(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMISampleProvider.java b/ev3classes/src/main/java/lejos/remote/ev3/RMISampleProvider.java deleted file mode 100644 index a79a964..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMISampleProvider.java +++ /dev/null @@ -1,10 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMISampleProvider extends Remote { - public float[] fetchSample() throws RemoteException; - - public void close() throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMITextLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RMITextLCD.java deleted file mode 100644 index eb91f2f..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMITextLCD.java +++ /dev/null @@ -1,56 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -import lejos.hardware.lcd.Font; - -public interface RMITextLCD extends Remote { - - public void refresh() throws RemoteException; - - public void clear() throws RemoteException; - - public int getWidth() throws RemoteException; - - public int getHeight() throws RemoteException; - - public byte[] getDisplay() throws RemoteException; - - public byte[] getHWDisplay() throws RemoteException; - - public void setContrast(int contrast) throws RemoteException; - - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, - int dy, int w, int h, int rop) throws RemoteException; - - 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) throws RemoteException; - - public void setAutoRefresh(boolean on) throws RemoteException; - - public int setAutoRefreshPeriod(int period) throws RemoteException; - - public void drawChar(char c, int x, int y) throws RemoteException; - - public void drawString(String str, int x, int y, boolean inverted) throws RemoteException; - - public void drawString(String str, int x, int y) throws RemoteException; - - public void drawInt(int i, int x, int y) throws RemoteException; - - public void drawInt(int i, int places, int x, int y) throws RemoteException; - - public void clear(int x, int y, int n) throws RemoteException; - - public void clear(int y) throws RemoteException; - - public void scroll() throws RemoteException; - - public Font getFont() throws RemoteException; - - public int getTextWidth() throws RemoteException; - - public int getTextHeight() throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIUARTPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIUARTPort.java deleted file mode 100644 index 86c0626..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIUARTPort.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMIUARTPort extends Remote { - - /** - * read a single byte from the device - * @return the byte value - */ - public byte getByte() throws RemoteException; - - /** - * read a number of bytes from the device - * @param vals byte array to accept the data - * @param offset offset at which to store the data - * @param len number of bytes to read - */ - public void getBytes(byte [] vals, int offset, int len) throws RemoteException; - - /** - * read a single short from the device. - * @return the short value - */ - public int getShort() throws RemoteException; - - /** - * read a number of shorts from the device - * @param vals short array to accept the data - * @param offset offset at which to store the data - * @param len number of shorts to read - */ - public void getShorts(short [] vals, int offset, int len) throws RemoteException; - - /** - * Get the string name of the specified mode.

    - * TODO: Make other mode data available. - * @param mode mode to lookup - * @return String version of the mode name - */ - public String getModeName(int mode) throws RemoteException; - - /** - * Return the current sensor reading to a string. - */ - public String toStringValue() throws RemoteException; - - /** - * Initialise the attached sensor and set it to the required operating mode.
    - * Note: This method is not normally needed as the sensor will be initialised - * when it is opened. However it may be of use if the sensor needs to be reset - * or in other cases. - * @param mode target mode - * @return true if ok false if error - */ - boolean initialiseSensor(int mode) throws RemoteException; - - /** - * Reset the attached sensor. Following this the sensor must be initialised - * before it can be used. - */ - void resetSensor() throws RemoteException; - - /** - * Write bytes to the sensor - * @param buffer bytes to be written - * @param offset offset to the start of the write - * @param len length of the write - * @return number of bytes written - */ - int write(byte[] buffer, int offset, int len) throws RemoteException; - - /** - * Read bytes from the uart port. If no bytes are available return 0.

    - * Note: The port must have been set into RAW mode to use this method. - * @param buffer The buffer to store the read bytes - * @param offset The offset at which to start storing the bytes - * @param len The maximum number of bytes to read - * @return The actual number of bytes read - */ - public int rawRead(byte[] buffer, int offset, int len) throws RemoteException; - - /** - * Attempt to write a series of bytes to the uart port. This call - * is non-blocking if there is no space in the write buffer a count - * of 0 is returned.

    - * Note: The port must have been set into RAW mode before attempting - * to use the method. - * @param buffer The buffer containing the bytes to write - * @param offset The offset of the first byte - * @param len The number of bytes to attempt to write - * @return The actual number of bytes written - */ - public int rawWrite(byte[] buffer, int offset, int len) throws RemoteException; - - /** - * Set the bit rate of the port when operating in RAW mode. - * @param bitRate The new bit rate - */ - public void setBitRate(int bitRate) throws RemoteException; - - - void close() throws RemoteException; - - boolean setMode(int mode) throws RemoteException; -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RMIWifi.java b/ev3classes/src/main/java/lejos/remote/ev3/RMIWifi.java deleted file mode 100644 index 50a0626..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RMIWifi.java +++ /dev/null @@ -1,12 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RMIWifi extends Remote { - - public String[] getAccessPointNames() throws RemoteException; - - public String getAccessPoint() throws RemoteException; - -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteAnalogPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteAnalogPort.java deleted file mode 100644 index c9abde4..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteAnalogPort.java +++ /dev/null @@ -1,108 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.PortException; - -public class RemoteAnalogPort extends RemoteIOPort implements AnalogPort { - protected RMIAnalogPort rmi; - protected RMIEV3 rmiEV3; - - public RemoteAnalogPort(RMIEV3 rmiEV3) { - this.rmiEV3 = rmiEV3; - } - - public boolean open(int typ, int portNum, RemotePort remotePort) { - boolean res = super.open(typ,portNum,remotePort); - try { - rmi = rmiEV3.openAnalogPort(getName()); - } catch (RemoteException e) { - throw new PortException(e); - } - return res; - } - - @Override - public void close() { - super.close(); - try { - rmi.close(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public float getPin6() { - try { - return rmi.getPin6(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public float getPin1() { - try { - return rmi.getPin1(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public boolean setPinMode(int mode) { - try { - return rmi.setPinMode(mode); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - // The following method provide compatibility with NXT sensors - - @Override - public boolean setType(int type) - { - switch(type) - { - case TYPE_NO_SENSOR: - case TYPE_SWITCH: - case TYPE_TEMPERATURE: - case TYPE_CUSTOM: - case TYPE_ANGLE: - setPinMode(CMD_FLOAT); - break; - case TYPE_LIGHT_ACTIVE: - case TYPE_SOUND_DBA: - case TYPE_REFLECTION: - setPinMode(CMD_SET|CMD_PIN5); - break; - case TYPE_LIGHT_INACTIVE: - case TYPE_SOUND_DB: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED_9V: - setPinMode(CMD_SET|CMD_PIN1); - break; - default: - throw new UnsupportedOperationException("Unrecognised sensor type"); - } - return true; - } - - - @Override - public void getFloats(float[] vals, int offset, int length) - { - try { - rmi.getFloats(vals, offset, length); - } catch (RemoteException e) { - throw new PortException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteAudio.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteAudio.java deleted file mode 100644 index 6ef6736..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteAudio.java +++ /dev/null @@ -1,105 +0,0 @@ -package lejos.remote.ev3; - -import java.io.File; -import java.rmi.RemoteException; - -import lejos.hardware.Audio; -import lejos.hardware.port.PortException; - -public class RemoteAudio implements Audio { - private RMIAudio audio; - - public RemoteAudio(RMIAudio audio) { - this.audio=audio; - } - - @Override - public void systemSound(int aCode) { - try { - audio.systemSound(aCode); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void playTone(int aFrequency, int aDuration, int aVolume) { - try { - audio.playTone(aFrequency, aDuration, aVolume); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void playTone(int freq, int duration) { - try { - audio.playTone(freq, duration); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int playSample(File file, int vol) { - try { - return audio.playSample(file, vol); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int playSample(File file) { - try { - return audio.playSample(file); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int playSample(byte[] data, int offset, int len, int freq, int vol) { - try { - return audio.playSample(data, offset, len, freq, vol); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void playNote(int[] inst, int freq, int len) { - try { - audio.playNote(inst, freq, len); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setVolume(int vol) { - try { - audio.setVolume(vol); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getVolume() { - try { - return audio.getVolume(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void loadSettings() { - try { - audio.loadSettings(); - } catch (RemoteException e) { - throw new PortException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteBattery.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteBattery.java deleted file mode 100644 index 2580247..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteBattery.java +++ /dev/null @@ -1,50 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; - -import lejos.hardware.Power; -import lejos.hardware.port.PortException; - -public class RemoteBattery implements Power { - RMIBattery battery; - - public RemoteBattery(RMIBattery battery) { - this.battery = battery; - } - - @Override - public int getVoltageMilliVolt() { - try { - return battery.getVoltageMilliVolt(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public float getVoltage() { - try { - return battery.getVoltage(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public float getBatteryCurrent() { - try { - return battery.getBatteryCurrent(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public float getMotorCurrent() { - try { - return battery.getMotorCurrent(); - } catch (RemoteException e) { - throw new PortException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteEV3.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteEV3.java deleted file mode 100644 index f646827..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteEV3.java +++ /dev/null @@ -1,199 +0,0 @@ -package lejos.remote.ev3; - -import java.net.MalformedURLException; -import java.rmi.Naming; -import java.rmi.NotBoundException; -import java.rmi.RemoteException; -import java.util.ArrayList; - -import lejos.hardware.Audio; -import lejos.hardware.BrickFinder; -import lejos.hardware.Key; -import lejos.hardware.Keys; -import lejos.hardware.LED; -import lejos.hardware.Power; -import lejos.hardware.LocalBTDevice; -import lejos.hardware.LocalWifiDevice; -import lejos.hardware.ev3.EV3; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.TextLCD; -import lejos.hardware.port.Port; -import lejos.hardware.port.PortException; -import lejos.hardware.video.Video; - -public class RemoteEV3 implements EV3 { - private String host; - private RMIEV3 rmiEV3; - private ArrayList ports = new ArrayList(); - private RemoteKeys keys; - - public RemoteEV3(String host) throws RemoteException, MalformedURLException, NotBoundException { - this.host = host; - rmiEV3 = (RMIEV3) Naming.lookup("//" + host + "/RemoteEV3"); - createPorts(); - keys = new RemoteKeys(rmiEV3.getKeys()); - } - - private void createPorts() { - // Create the port objects - ports.add(new RemotePort("S1", RemotePort.SENSOR_PORT, 0, rmiEV3)); - ports.add(new RemotePort("S2", RemotePort.SENSOR_PORT, 1, rmiEV3)); - ports.add(new RemotePort("S3", RemotePort.SENSOR_PORT, 2, rmiEV3)); - ports.add(new RemotePort("S4", RemotePort.SENSOR_PORT, 3, rmiEV3)); - ports.add(new RemotePort("A", RemotePort.MOTOR_PORT, 0, rmiEV3)); - ports.add(new RemotePort("B", RemotePort.MOTOR_PORT, 1, rmiEV3)); - ports.add(new RemotePort("C", RemotePort.MOTOR_PORT, 2, rmiEV3)); - ports.add(new RemotePort("D", RemotePort.MOTOR_PORT, 3, rmiEV3)); - } - - @Override - public Port getPort(String portName) { - for(RemotePort p : ports) - if (p.getName().equals(portName)) - return p; - throw new IllegalArgumentException("No such port " + portName); - } - - @Override - public Power getPower() { - try { - return new RemoteBattery(rmiEV3.getBattery()); - } catch (RemoteException e) { - e.printStackTrace(); - return null; - } - } - - public String getHost() { - return host; - } - - public RMISampleProvider createSampleProvider(String portName, String sensorName, String modeName) { - try { - return rmiEV3.createSampleProvider(portName, sensorName, modeName); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public RMIRegulatedMotor createRegulatedMotor(String portName, char motorType) { - try { - return rmiEV3.createRegulatedMotor(portName, motorType); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public Audio getAudio() { - try { - return new RemoteAudio(rmiEV3.getAudio()); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public Video getVideo() { - // TODO: Should this be remote? - return null; - } - - public TextLCD getTextLCD() { - try { - return new RemoteTextLCD(rmiEV3.getTextLCD()); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public RMIWifi getWifi() { - try { - return rmiEV3.getWifi(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public RMIBluetooth getBluetooth() { - try { - return rmiEV3.getBluetooth(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public GraphicsLCD getGraphicsLCD() { - try { - return new RemoteGraphicsLCD(rmiEV3.getGraphicsLCD()); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public TextLCD getTextLCD(Font f) { - try { - return new RemoteTextLCD(rmiEV3.getTextLCD(f)); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public boolean isLocal() { - return false; - } - - @Override - public String getType() { - return "EV3"; - } - - @Override - public String getName() { - try { - return rmiEV3.getName(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public LocalBTDevice getBluetoothDevice() { - return null; - } - - @Override - public LocalWifiDevice getWifiDevice() { - return null; - } - - @Override - public void setDefault() { - BrickFinder.setDefault(this); - } - - @Override - public Key getKey(String name) { - try { - return new RemoteKey(rmiEV3.getKey(name), keys, name); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public LED getLED() { - try { - return new RemoteLED(rmiEV3.getLED()); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public Keys getKeys() { - return keys; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteGraphicsLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteGraphicsLCD.java deleted file mode 100644 index 9169c3f..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteGraphicsLCD.java +++ /dev/null @@ -1,369 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; - -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.Image; -import lejos.hardware.port.PortException; - -public class RemoteGraphicsLCD implements GraphicsLCD { - private RMIGraphicsLCD g; - - public RemoteGraphicsLCD(RMIGraphicsLCD g) { - this.g = g; - } - - @Override - public void refresh() { - try { - g.refresh(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void clear() { - try { - g.clear(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getWidth() { - try { - return g.getWidth(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getHeight() { - try { - return g.getHeight(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public byte[] getDisplay() { - try { - return g.getDisplay(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public byte[] getHWDisplay() { - try { - return g.getHWDisplay(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setContrast(int contrast) { - try { - g.setContrast(contrast); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, - int dy, int w, int h, int rop) { - try { - g.bitBlt(src, sw, sh, sx, sy, dx, dy, w, h, rop); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @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) { - try { - g.bitBlt(src, sw, sh, sx, sy, dst, dw, dh, dx, dy, w, h, rop); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setAutoRefresh(boolean on) { - try { - g.setAutoRefresh(on); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int setAutoRefreshPeriod(int period) { - try { - return g.setAutoRefreshPeriod(period); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setPixel(int x, int y, int color) { - try { - g.setPixel(x, y, color); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getPixel(int x, int y) { - try { - return g.getPixel(x, y); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawString(String str, int x, int y, int anchor, - boolean inverted) { - try { - g.drawString(str, x, y, anchor, inverted); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawString(String str, int x, int y, int anchor) { - try { - g.drawString(str, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawSubstring(String str, int offset, int len, int x, int y, - int anchor) { - try { - g.drawSubstring(str, offset, len, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawChar(char character, int x, int y, int anchor) { - try { - g.drawChar(character, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawChars(char[] data, int offset, int length, int x, int y, - int anchor) { - try { - g.drawChars(data, offset, length, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getStrokeStyle() { - try { - return g.getStrokeStyle(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setStrokeStyle(int style) { - try { - g.setStrokeStyle(style); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, - int y, int anchor, int rop) { - try { - g.drawRegionRop(src, sx, sy, w, h, x, y, anchor, rop); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor, int rop) { - try { - g.drawRegionRop(src, sx, sy, w, h, transform, x, y, anchor, rop); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawRegion(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor) { - try { - g.drawRegion(src, sx, sy, w, h, transform, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawImage(Image src, int x, int y, int anchor) { - try { - g.drawImage(src, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawLine(int x0, int y0, int x1, int y1) { - try { - g.drawLine(x0, y0, x1, y1); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - try { - g.drawArc(x, y, width, height, startAngle, arcAngle); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - try { - g.fillArc(x, y, width, height, startAngle, arcAngle); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - try { - g.drawRoundRect(x, y, width, height, arcWidth, arcHeight); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void drawRect(int x, int y, int width, int height) { - try { - g.drawRect(x, y, width, height); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void fillRect(int x, int y, int w, int h) { - try { - g.fillRect(x, y, w, h); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void copyArea(int sx, int sy, int w, int h, int x, int y, int anchor) { - try { - g.copyArea(sx, sy, w, h, x, y, anchor); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public Font getFont() { - try { - return g.getFont(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setFont(Font f) { - try { - g.setFont(f); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void translate(int x, int y) { - try { - g.translate(x, y); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getTranslateX() { - try { - return g.getTranslateX(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getTranslateY() { - try { - return g.getTranslateY(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setColor(int rgb) { - try { - g.setColor(rgb); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setColor(int red, int green, int blue) { - try { - g.setColor(red, green, blue); - } catch (RemoteException e) { - throw new PortException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteI2CPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteI2CPort.java deleted file mode 100644 index d217949..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteI2CPort.java +++ /dev/null @@ -1,58 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; - -import lejos.hardware.port.I2CException; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.PortException; - -public class RemoteI2CPort extends RemoteIOPort implements I2CPort { - protected RMII2CPort rmi; - protected RMIEV3 rmiEV3; - - public RemoteI2CPort(RMIEV3 rmiEV3) { - this.rmiEV3 = rmiEV3; - } - - public boolean open(int typ, int portNum, RemotePort remotePort) { - boolean res = super.open(typ,portNum,remotePort); - try { - rmi = rmiEV3.openI2CPort(getName()); - } catch (RemoteException e) { - throw new PortException(e); - } - return res; - } - - - @Override - public void close() { - try { - super.close(); - rmi.close(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void i2cTransaction(int deviceAddress, byte[] writeBuf, - int writeOffset, int writeLen, byte[] readBuf, int readOffset, int readLen) { - try { - byte[] res = rmi.i2cTransaction(deviceAddress, writeBuf, writeOffset, writeLen, readLen); - if (res == null) throw new I2CException("RMI I2C Error"); - System.arraycopy(res, 0, readBuf, readOffset, readLen); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public boolean setType(int type) { - try { - return rmi.setType(type); - } catch (RemoteException e) { - throw new PortException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteIOPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteIOPort.java deleted file mode 100644 index 717b537..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteIOPort.java +++ /dev/null @@ -1,79 +0,0 @@ -package lejos.remote.ev3; - -import lejos.hardware.port.BasicSensorPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.sensor.EV3SensorConstants; -import lejos.remote.nxt.RemoteNXTPort; - -public class RemoteIOPort implements IOPort, BasicSensorPort, EV3SensorConstants { - protected int port = -1; - protected int typ = -1; - protected RemotePort ref; - protected int currentMode = 0; - protected static RemoteIOPort [][] openPorts = new RemoteIOPort[RemoteNXTPort.MOTOR_PORT+1][PORTS]; - - public boolean open(int typ, int port, RemotePort ref) { - synchronized (openPorts) - { - if (openPorts[typ][port] == null) - { - openPorts[typ][port] = this; - this.port = port; - this.typ = typ; - this.ref = ref; - return true; - } - return false; - } - } - - @Override - public int getMode() { - return currentMode; - } - - @Override - public int getType() { - return 0; - } - - @Override - public boolean setMode(int mode) { - currentMode = mode; - return false; - } - - @Override - public boolean setType(int type) { - throw new UnsupportedOperationException("This operation is for legacy modes only"); - } - - @Override - public boolean setTypeAndMode(int type, int mode) { - setType(type); - setMode(mode); - return true; - } - - @Override - public void close() { - if (port == -1) - throw new IllegalStateException("Port is not open"); - synchronized (openPorts) - { - openPorts[typ][port] = null; - port = -1; - } - } - - @Override - public String getName() { - return ref.getName(); - } - - @Override - public boolean setPinMode(int mode) { - // Overridden by specific port implementations - return false; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteKey.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteKey.java deleted file mode 100644 index 8caf037..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteKey.java +++ /dev/null @@ -1,103 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.util.ArrayList; - -import lejos.hardware.Key; -import lejos.hardware.KeyListener; -import lejos.hardware.port.PortException; -import lejos.internal.ev3.EV3Key; - -public class RemoteKey implements Key { - private RMIKey key; - private RemoteKeys keys; - private int iCode; - private String name; - - private ArrayList listeners; - - public RemoteKey(RMIKey key, RemoteKeys keys, String name) { - this.keys = keys; - this.iCode = EV3Key.getKeyId(name); - this.key=key; - this.name = name; - } - - @Override - public int getId() { - try { - return key.getId(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public boolean isDown() { - try { - return key.isDown(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public boolean isUp() { - try { - return key.isUp(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void waitForPress() { - try { - key.waitForPress(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void waitForPressAndRelease() { - try { - key.waitForPressAndRelease(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void addKeyListener(KeyListener listener) { - if (listeners == null) { - listeners = new ArrayList(); - } - listeners.add(listener); - keys.addListener(iCode, this); - } - - @Override - public void simulateEvent(int event) { - try { - key.simulateEvent(event); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public void callListeners() { - boolean pressed = isDown(); - - if (listeners != null) - for(KeyListener listener: listeners) { - if (pressed) listener.keyPressed(this); - else listener.keyReleased(this); - } - } - - @Override - public String getName() { - return name; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteKeys.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteKeys.java deleted file mode 100644 index 586bd43..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteKeys.java +++ /dev/null @@ -1,169 +0,0 @@ -package lejos.remote.ev3; - -import java.rmi.RemoteException; -import java.util.HashMap; -import java.util.Map; - -import lejos.hardware.Keys; -import lejos.hardware.port.PortException; - -public class RemoteKeys implements Keys { - private RMIKeys keys; - private Map listeners; - - private static final int PRESS_EVENT_SHIFT = 0; - private static final int RELEASE_EVENT_SHIFT = 8; - - public RemoteKeys(RMIKeys keys) { - this.keys=keys; - } - - @Override - public void discardEvents() { - try { - keys.discardEvents(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int waitForAnyEvent() { - try { - return keys.waitForAnyEvent(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int waitForAnyEvent(int timeout) { - try { - return keys.waitForAnyEvent(timeout); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int waitForAnyPress(int timeout) { - try { - return keys.waitForAnyPress(timeout); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int waitForAnyPress() { - try { - return keys.waitForAnyPress(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getButtons() { - try { - return keys.getButtons(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int readButtons() { - try { - return keys.readButtons(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setKeyClickVolume(int vol) { - try { - keys.setKeyClickVolume(vol); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getKeyClickVolume() { - try { - return keys.getKeyClickVolume(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setKeyClickLength(int len) { - try { - keys.setKeyClickLength(len); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getKeyClickLength() { - try { - return keys.getKeyClickLength(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public void setKeyClickTone(int key, int freq) { - try { - keys.setKeyClickTone(key, freq); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public int getKeyClickTone(int key) { - try { - return keys.getKeyClickTone(key); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - void addListener(int iCode,RemoteKey key) { - if (listeners == null) { - listeners = new HashMap(); - new KeysListenThread().start(); - } - listeners.put(iCode, key); - } - - class KeysListenThread extends Thread { - - public KeysListenThread() { - setDaemon(true); - } - - @Override - public void run() { - while (true) { - int state = RemoteKeys.this.waitForAnyEvent(); - - int mask = 1; - for (int i=0;iBasicMotorPort. 1=forward, 2=backward, 3=stop, 4=float. - * @see BasicMotorPort#FORWARD - * @see BasicMotorPort#BACKWARD - * @see BasicMotorPort#FLOAT - * @see BasicMotorPort#STOP - */ - public void controlMotor(int power, int mode) - { - try { - rmi.controlMotor(power, mode); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - - /** - * returns tachometer count - */ - public int getTachoCount() - { - try { - return rmi.getTachoCount(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - /** - *resets the tachometer count to 0; - */ - public void resetTachoCount() - { - try { - rmi.resetTachoCount(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public void setPWMMode(int mode) - { - try { - rmi.setPWMMode(mode); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - public void close() { - try { - rmi.close(); - } catch (RemoteException e) { - throw new PortException(e); - } - } - - @Override - public MotorRegulator getRegulator() - { - // TODO Does it make sense to allow this to be remote? - throw(new UnsupportedOperationException("Remote regulators are not supported")); - //return null; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemotePort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemotePort.java deleted file mode 100644 index 72276ef..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemotePort.java +++ /dev/null @@ -1,74 +0,0 @@ -package lejos.remote.ev3; - -import lejos.hardware.DeviceException; -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.port.UARTPort; -import lejos.hardware.sensor.EV3SensorConstants; - -public class RemotePort implements Port -{ - public static final int SENSOR_PORT = 0; - public static final int MOTOR_PORT = 1; - protected String name; - protected int typ; - protected int portNum; - protected RMIEV3 rmiEV3; - - public RemotePort(String name, int typ, int portNum, RMIEV3 rmiEV3) - { - if (typ < SENSOR_PORT || typ > MOTOR_PORT) - throw new IllegalArgumentException("Invalid port type"); - if (portNum < 0 || - (typ == SENSOR_PORT && portNum >= EV3SensorConstants.PORTS) || - (typ == MOTOR_PORT && portNum >= EV3SensorConstants.MOTORS)) - throw new IllegalArgumentException("Invalid port number"); - this.name = name; - this.typ = typ; - this.portNum = portNum; - this.rmiEV3 = rmiEV3; - } - - /** {@inheritDoc} - */ - @Override - public String getName() - { - return name; - } - - /** {@inheritDoc} - */ - @Override - public T open(Class portclass) - { - RemoteIOPort p = null; - switch(typ) - { - case SENSOR_PORT: - if (portclass == RemoteUARTPort.class || portclass == UARTPort.class) - p = new RemoteUARTPort(rmiEV3); - if (portclass == RemoteAnalogPort.class || portclass == AnalogPort.class) - p = new RemoteAnalogPort(rmiEV3); - else if (portclass == RemoteI2CPort.class|| portclass == I2CPort.class) - p = new RemoteI2CPort(rmiEV3); - break; - case MOTOR_PORT: - if (portclass == BasicMotorPort.class) - p = new RemoteMotorPort(rmiEV3); - else if (portclass == TachoMotorPort.class) - p = new RemoteMotorPort(rmiEV3); - // TODO: Should we also allow Encoder? - break; - } - if (p == null) - throw new IllegalArgumentException("Invalid port interface"); - if (!p.open(typ, portNum, this)) - throw new DeviceException("unable to open port"); - return portclass.cast(p); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestAnalogPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestAnalogPort.java deleted file mode 100644 index 22cc142..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestAnalogPort.java +++ /dev/null @@ -1,116 +0,0 @@ -package lejos.remote.ev3; - -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import lejos.hardware.port.AnalogPort; - -public class RemoteRequestAnalogPort extends RemoteRequestIOPort implements AnalogPort { - private ObjectInputStream is; - private ObjectOutputStream os; - private int portNum; - - public RemoteRequestAnalogPort(ObjectInputStream is, ObjectOutputStream os) { - this.is = is; - this.os = os; - } - - @Override - public boolean open(int typ, int portNum, - RemoteRequestPort remoteRequestPort) { - boolean res = super.open(typ,portNum,remoteRequestPort); - this.portNum = portNum; - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.OPEN_ANALOG_PORT;; - req.intValue2 = typ; - sendRequest(req, true); - return res; - } - - @Override - public void close() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.CLOSE_SENSOR_PORT; - sendRequest(req, false); - } - - @Override - public boolean setType(int type) - { - switch(type) - { - case TYPE_NO_SENSOR: - case TYPE_SWITCH: - case TYPE_TEMPERATURE: - case TYPE_CUSTOM: - case TYPE_ANGLE: - setPinMode(CMD_FLOAT); - break; - case TYPE_LIGHT_ACTIVE: - case TYPE_SOUND_DBA: - case TYPE_REFLECTION: - setPinMode(CMD_SET|CMD_PIN5); - break; - case TYPE_LIGHT_INACTIVE: - case TYPE_SOUND_DB: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED: - setPinMode(CMD_SET); - break; - case TYPE_LOWSPEED_9V: - setPinMode(CMD_SET|CMD_PIN1); - break; - default: - throw new UnsupportedOperationException("Unrecognised sensor type"); - } - return true; - } - - @Override - public boolean setPinMode(int mode) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.SET_PIN_MODE; - req.intValue = portNum; - return sendRequest(req, true).result; - } - - @Override - public float getPin6() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.GET_PIN_6; - return sendRequest(req, true).floatReply; - } - - @Override - public float getPin1() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.GET_PIN_1; - return sendRequest(req, true).floatReply; - } - - @Override - public void getFloats(float[] vals, int offset, int length) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.GET_FLOATS; - EV3Reply reply = sendRequest(req, true); - for(int i=0;i ports = new ArrayList(); - private RemoteRequestKeys keys; - - private static final int PORT = 8002; - - public RemoteRequestEV3(String host) throws IOException { - socket = new Socket(host,PORT); - socket.setTcpNoDelay(true); - is = new ObjectInputStream(socket.getInputStream()); - os = new ObjectOutputStream(socket.getOutputStream()); - createPorts(); - keys = new RemoteRequestKeys(is, os); - } - - private void createPorts() { - // Create the port objects - ports.add(new RemoteRequestPort("S1", RemoteRequestPort.SENSOR_PORT, 0, is, os)); - ports.add(new RemoteRequestPort("S2", RemoteRequestPort.SENSOR_PORT, 1, is, os)); - ports.add(new RemoteRequestPort("S3", RemoteRequestPort.SENSOR_PORT, 2, is, os)); - ports.add(new RemoteRequestPort("S4", RemoteRequestPort.SENSOR_PORT, 3, is, os)); - ports.add(new RemoteRequestPort("A", RemoteRequestPort.MOTOR_PORT, 0, is, os)); - ports.add(new RemoteRequestPort("B", RemoteRequestPort.MOTOR_PORT, 1, is, os)); - ports.add(new RemoteRequestPort("C", RemoteRequestPort.MOTOR_PORT, 2, is, os)); - ports.add(new RemoteRequestPort("D", RemoteRequestPort.MOTOR_PORT, 3, is, os)); - } - - @Override - public Port getPort(String portName) { - for(RemoteRequestPort p : ports) - if (p.getName().equals(portName)) - return p; - throw new IllegalArgumentException("No such port " + portName); - } - - @Override - public Power getPower() { - return new RemoteRequestBattery(is, os); - } - - @Override - public Audio getAudio() { - return new RemoteRequestAudio(is, os); - } - - @Override - public Video getVideo() { - return null; - } - - @Override - public TextLCD getTextLCD() { - return new RemoteRequestTextLCD(is, os); - } - - @Override - public TextLCD getTextLCD(Font f) { - return new RemoteRequestTextLCD(is, os, f); - } - - @Override - public GraphicsLCD getGraphicsLCD() { - return new RemoteRequestGraphicsLCD(is, os); - } - - @Override - public boolean isLocal() { - return false; - } - - @Override - public String getType() { - return "EV3"; - } - - @Override - public String getName() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.GET_NAME; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.name; - } catch (Exception e) { - return "Not knon"; - } - } - - @Override - public LocalBTDevice getBluetoothDevice() { - return null; - } - - @Override - public LocalWifiDevice getWifiDevice() { - return null; - } - - @Override - public void setDefault() { - BrickFinder.setDefault(this); - } - - @Override - public Keys getKeys() { - return keys; - } - - @Override - public Key getKey(String name) { - return new RemoteRequestKey(is, os, keys, name); - } - - @Override - public LED getLED() { - return new RemoteRequestLED(is,os); - } - - public SampleProvider createSampleProvider(String portName, String sensorName, String modeName) { - return new RemoteRequestSampleProvider(is,os, portName, sensorName, modeName); - } - - public SampleProvider createSampleProvider(String portName, - String sensorName, String modeName, String topic, float frequency) throws RemoteException { - return new RemoteRequestSampleProvider(is, os, portName, sensorName, modeName, topic, frequency); - } - - public RegulatedMotor createRegulatedMotor(String portName, char motorType) { - return new RemoteRequestRegulatedMotor(is, os, portName, motorType); - } - - - public ArcRotateMoveController createPilot(double wheelDiameter, double trackWidth, String leftMotor, String rightMotor) { - return new RemoteRequestPilot(is, os, leftMotor, rightMotor, wheelDiameter, trackWidth); - } - - public void disConnect() { - try { - os.flush(); - is.close(); - os.close(); - socket.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestException.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestException.java deleted file mode 100644 index 718598c..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestException.java +++ /dev/null @@ -1,33 +0,0 @@ -package lejos.remote.ev3; - -/** - * Exception thrown when errors are detected in a sensor device state. - * @author andy - * - */ -public class RemoteRequestException extends RuntimeException -{ - /** - * - */ - private static final long serialVersionUID = 5846698127613306496L; - - public RemoteRequestException() - { - } - - public RemoteRequestException(String message) - { - super (message); - } - - public RemoteRequestException(Throwable cause) - { - super (cause); - } - - public RemoteRequestException(String message, Throwable cause) - { - super (message, cause); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestGraphicsLCD.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestGraphicsLCD.java deleted file mode 100644 index c976707..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestGraphicsLCD.java +++ /dev/null @@ -1,472 +0,0 @@ -package lejos.remote.ev3; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.Image; - -public class RemoteRequestGraphicsLCD implements GraphicsLCD { - private ObjectInputStream is; - private ObjectOutputStream os; - - public RemoteRequestGraphicsLCD(ObjectInputStream is, ObjectOutputStream os) { - this.is = is; - this.os = os; - } - - @Override - public void refresh() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_REFRESH; - sendRequest(req, false); - } - - @Override - public void clear() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_CLEAR; - sendRequest(req, false); - } - - @Override - public int getWidth() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_GET_WIDTH; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.reply; - } catch (Exception e) { - return 0; - } - } - - @Override - public int getHeight() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_GET_HEIGHT; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.reply; - } catch (Exception e) { - return 0; - } - } - - @Override - public byte[] getDisplay() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_GET_DISPLAY; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.contents; - } catch (Exception e) { - return null; - } - } - - @Override - public byte[] getHWDisplay() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_GET_HW_DISPLAY; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.contents; - } catch (Exception e) { - return null; - } - } - - @Override - public void setContrast(int contrast) { - // Not implemented - } - - @Override - public void bitBlt(byte[] src, int sw, int sh, int sx, int sy, int dx, - int dy, int w, int h, int rop) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_BITBLT_1; - req.byteData = src; - req.intValue = sw; - req.intValue2 = sh; - req.intValue3 = sx; - req.intValue4 = sy; - req.intValue5 = dx; - req.intValue6 = dy; - req.intValue7 = w; - req.intValue8 = h; - req.intValue9 = rop; - sendRequest(req, false); - } - - @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) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_BITBLT_2; - req.byteData = src; - req.intValue = sw; - req.intValue2 = sh; - req.intValue3 = sx; - req.intValue4 = sy; - req.byteData2 = dst; - req.intValue5 = dw; - req.intValue6 = dh; - req.intValue7 = dx; - req.intValue8 = dy; - req.intValue9 = w; - req.intValue10 = h; - req.intValue11 = rop; - sendRequest(req, false); - } - - @Override - public void setAutoRefresh(boolean on) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_SET_AUTO_REFRESH; - req.flag = on; - sendRequest(req, false); - } - - @Override - public int setAutoRefreshPeriod(int period) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_SET_AUTO_REFRESH; - req.intValue = period; - try { - os.writeObject(req); - return 0; - } catch (IOException e) { - return 0; - } - } - - @Override - public void setPixel(int x, int y, int color) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = color; - req.request = EV3Request.Request.LCD_G_SET_PIXEL; - sendRequest(req, false); - } - - @Override - public int getPixel(int x, int y) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.request = EV3Request.Request.LCD_G_GET_PIXEL; - return sendRequest(req, true).reply; - } - - @Override - public void drawString(String str, int x, int y, int anchor, - boolean inverted) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = anchor; - req.str = str; - req.flag = inverted; - req.request = EV3Request.Request.LCD_G_DRAW_STRING_INVERTED; - sendRequest(req, false); - } - - @Override - public void drawString(String str, int x, int y, int anchor) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = anchor; - req.str = str; - req.request = EV3Request.Request.LCD_G_DRAW_STRING; - sendRequest(req, false); - } - - @Override - public void drawSubstring(String str, int offset, int len, int x, int y, - int anchor) { - EV3Request req = new EV3Request(); - req.intValue = offset; - req.intValue2 = x; - req.intValue3 = y; - req.intValue4 = anchor; - req.str = str; - req.request = EV3Request.Request.LCD_G_DRAW_SUBSTRING; - sendRequest(req, false); - } - - @Override - public void drawChar(char character, int x, int y, int anchor) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = anchor; - req.ch = character; - req.request = EV3Request.Request.LCD_G_DRAW_CHAR; - sendRequest(req, false); - } - - @Override - public void drawChars(char[] data, int offset, int length, int x, int y, - int anchor) { - EV3Request req = new EV3Request(); - req.intValue = offset; - req.intValue2 = x; - req.intValue3 = y; - req.intValue4 = anchor; - req.chars = data; - req.request = EV3Request.Request.LCD_G_DRAW_CHARS; - sendRequest(req, false); - } - - @Override - public int getStrokeStyle() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_G_GET_STROKE_STYLE; - return sendRequest(req, true).reply; - } - - @Override - public void setStrokeStyle(int style) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_G_SET_STROKE_STYLE; - sendRequest(req, false); - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, int x, - int y, int anchor, int rop) { - EV3Request req = new EV3Request(); - req.image = src; - req.intValue = sx; - req.intValue2 = sy; - req.intValue3 = w; - req.intValue4 = h; - req.intValue5 = x; - req.intValue6 = y; - req.intValue7 = anchor; - req.intValue8 = rop; - req.request = EV3Request.Request.LCD_G_DRAW_REGION_ROP; - sendRequest(req, false); - } - - @Override - public void drawRegionRop(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor, int rop) { - EV3Request req = new EV3Request(); - req.image = src; - req.intValue = sx; - req.intValue2 = sy; - req.intValue3 = w; - req.intValue4 = h; - req.intValue5 = transform; - req.intValue6 = x; - req.intValue7 = y; - req.intValue8 = anchor; - req.intValue9 = rop; - req.request = EV3Request.Request.LCD_G_DRAW_REGION_ROP_TRANSFORM; - sendRequest(req, false); - } - - @Override - public void drawRegion(Image src, int sx, int sy, int w, int h, - int transform, int x, int y, int anchor) { - EV3Request req = new EV3Request(); - req.image = src; - req.intValue = sx; - req.intValue2 = sy; - req.intValue3 = w; - req.intValue4 = h; - req.intValue5 = transform; - req.intValue6 = x; - req.intValue7 = y; - req.intValue8 = anchor; - req.request = EV3Request.Request.LCD_G_DRAW_REGION; - sendRequest(req, false); - } - - @Override - public void drawImage(Image src, int x, int y, int anchor) { - EV3Request req = new EV3Request(); - req.image = src; - req.intValue = x; - req.intValue2 = y; - req.intValue3 = anchor; - req.request = EV3Request.Request.LCD_G_DRAW_IMAGE; - sendRequest(req, false); - } - - @Override - public void drawLine(int x0, int y0, int x1, int y1) { - EV3Request req = new EV3Request(); - req.intValue = x0; - req.intValue2 = y0; - req.intValue3 = x1; - req.intValue4 = y1; - req.request = EV3Request.Request.LCD_G_DRAW_LINE; - sendRequest(req, false); - } - - @Override - public void drawArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = width; - req.intValue4 = height; - req.intValue5 = startAngle; - req.intValue6 = arcAngle; - req.request = EV3Request.Request.LCD_G_DRAW_ARC; - sendRequest(req, false); - } - - @Override - public void fillArc(int x, int y, int width, int height, int startAngle, - int arcAngle) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = width; - req.intValue4 = height; - req.intValue5 = startAngle; - req.intValue6 = arcAngle; - req.request = EV3Request.Request.LCD_G_FILL_ARC; - sendRequest(req, false); - } - - @Override - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = width; - req.intValue4 = height; - req.intValue5 = arcWidth; - req.intValue6 = arcHeight; - req.request = EV3Request.Request.LCD_G_DRAW_ROUND_RECT; - sendRequest(req, false); - } - - @Override - public void drawRect(int x, int y, int width, int height) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = width; - req.intValue4 = height; - req.request = EV3Request.Request.LCD_G_DRAW_RECT; - sendRequest(req, false); - } - - @Override - public void fillRect(int x, int y, int w, int h) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = w; - req.intValue4 = h; - req.request = EV3Request.Request.LCD_G_FILL_RECT; - sendRequest(req, false); - } - - @Override - public void copyArea(int sx, int sy, int w, int h, int x, int y, int anchor) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.intValue3 = w; - req.intValue4 = h; - req.intValue5 = anchor; - req.request = EV3Request.Request.LCD_G_COPY_AREA; - sendRequest(req, false); - } - - @Override - public Font getFont() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setFont(Font f) { - // TODO Auto-generated method stub - } - - @Override - public void translate(int x, int y) { - EV3Request req = new EV3Request(); - req.intValue = x; - req.intValue2 = y; - req.request = EV3Request.Request.LCD_G_TRANSLATE; - sendRequest(req, false); - } - - @Override - public int getTranslateX() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_G_GET_TRANSLATE_X; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.reply; - } catch (Exception e) { - return 0; - } - } - - @Override - public int getTranslateY() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.LCD_G_GET_TRANSLATE_Y; - req.replyRequired = true; - try { - os.writeObject(req); - EV3Reply reply = (EV3Reply) is.readObject(); - return reply.reply; - } catch (Exception e) { - return 0; - } - } - - @Override - public void setColor(int rgb) { - // TODO Auto-generated method stub - } - - @Override - public void setColor(int red, int green, int blue) { - // TODO Auto-generated method stub - } - - private EV3Reply sendRequest(EV3Request req, boolean replyRequired) { - EV3Reply reply = null; - req.replyRequired = replyRequired; - try { - os.reset(); - os.writeObject(req); - if (replyRequired) { - reply = (EV3Reply) is.readObject(); - if (reply.e != null) throw new RemoteRequestException(reply.e); - } - return reply; - } catch (Exception e) { - throw new RemoteRequestException(e); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestI2CPort.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestI2CPort.java deleted file mode 100644 index 81b6452..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestI2CPort.java +++ /dev/null @@ -1,68 +0,0 @@ -package lejos.remote.ev3; - -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import lejos.hardware.port.I2CPort; - -public class RemoteRequestI2CPort extends RemoteRequestIOPort implements I2CPort { - private ObjectInputStream is; - private ObjectOutputStream os; - private int portNum; - - public RemoteRequestI2CPort(ObjectInputStream is, ObjectOutputStream os) { - this.is = is; - this.os = os; - } - - @Override - public boolean open(int typ, int portNum, - RemoteRequestPort remoteRequestPort) { - boolean res = super.open(typ,portNum,remoteRequestPort); - this.portNum = portNum; - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.OPEN_I2C_PORT; - req.intValue2 = typ; - sendRequest(req, true); - return res; - } - - @Override - public void close() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.CLOSE_SENSOR_PORT; - sendRequest(req, false); - } - - @Override - public void i2cTransaction(int deviceAddress, byte[] writeBuf, - int writeOffset, int writeLen, byte[] readBuf, int readOffset, - int readLen) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.I2C_TRANSACTION; - req.intValue2 = deviceAddress; - req.intValue3 = writeOffset; - req.intValue4 = writeLen; - req.intValue5 = readLen; - req.byteData = writeBuf; - EV3Reply reply = sendRequest(req, true); - for(int i=0;i listeners; - - public RemoteRequestKey(ObjectInputStream is, ObjectOutputStream os, RemoteRequestKeys keys, String name) { - this.is = is; - this.os = os; - this.keys = keys; - this.name = name; - this.iCode = EV3Key.getKeyId(name); - } - - @Override - public int getId() { - return iCode; - } - - @Override - public boolean isDown() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.KEY_IS_DOWN; - req.str = name; - return sendRequest(req, true).result; - } - - @Override - public boolean isUp() { - return !isDown(); - } - - @Override - public void waitForPress() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.KEY_WAIT_FOR_PRESS; - req.str = name; - sendRequest(req, true); - } - - @Override - public void waitForPressAndRelease() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.KEY_WAIT_FOR_PRESS_AND_RELEASE; - req.str = name; - sendRequest(req, true); - } - - @Override - public void addKeyListener(KeyListener listener) { - if (listeners == null) { - listeners = new ArrayList(); - } - listeners.add(listener); - keys.addListener(iCode, this); - } - - @Override - public void simulateEvent(int event) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.KEY_SIMULATE_EVENT; - req.str = name; - req.intValue = event; - sendRequest(req, true); - } - - private EV3Reply sendRequest(EV3Request req, boolean replyRequired) { - EV3Reply reply = null; - req.replyRequired = replyRequired; - try { - os.reset(); - os.writeObject(req); - if (replyRequired) { - reply = (EV3Reply) is.readObject(); - if (reply.e != null) throw new RemoteRequestException(reply.e); - } - return reply; - } catch (Exception e) { - throw new RemoteRequestException(e); - } - } - - @Override - public String getName() { - return name; - } - - public void callListeners() { - boolean pressed = isDown(); - - if (listeners != null) - for(KeyListener listener: listeners) { - if (pressed) listener.keyPressed(this); - else listener.keyReleased(this); - } - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestKeys.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestKeys.java deleted file mode 100644 index fb27d0d..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestKeys.java +++ /dev/null @@ -1,145 +0,0 @@ -package lejos.remote.ev3; - -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.HashMap; -import java.util.Map; - -import lejos.hardware.Keys; - -public class RemoteRequestKeys implements Keys { - private ObjectInputStream is; - private ObjectOutputStream os; - - private Map listeners; - - private static final int PRESS_EVENT_SHIFT = 0; - private static final int RELEASE_EVENT_SHIFT = 8; - - public RemoteRequestKeys(ObjectInputStream is, ObjectOutputStream os) { - this.is = is; - this.os = os; - } - - @Override - public void discardEvents() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.DISCARD_EVENTS; - sendRequest(req, false); - } - - @Override - public int waitForAnyEvent() { - return waitForAnyEvent(0); - } - - @Override - public int waitForAnyEvent(int timeout) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.WAIT_FOR_ANY_EVENT; - req.intValue= timeout; - return sendRequest(req, true).reply; - } - - @Override - public int waitForAnyPress(int timeout) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.WAIT_FOR_ANY_PRESS; - req.intValue = timeout; - return sendRequest(req, true).reply; - } - - @Override - public int waitForAnyPress() { - return waitForAnyPress(0); - } - - @Override - public int getButtons() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.GET_BUTTONS; - return sendRequest(req, true).reply; - } - - @Override - public int readButtons() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.READ_BUTTONS; - return sendRequest(req, true).reply; - } - - @Override - public void setKeyClickVolume(int vol) { - } - - @Override - public int getKeyClickVolume() { - return 0; - } - - @Override - public void setKeyClickLength(int len) { - } - - @Override - public int getKeyClickLength() { - return 0; - } - - @Override - public void setKeyClickTone(int key, int freq) { - - } - - @Override - public int getKeyClickTone(int key) { - return 0; - } - - void addListener(int iCode,RemoteRequestKey remoteRequestKey) { - if (listeners == null) { - listeners = new HashMap(); - new KeysListenThread().start(); - } - listeners.put(iCode, remoteRequestKey); - } - - private EV3Reply sendRequest(EV3Request req, boolean replyRequired) { - EV3Reply reply = null; - req.replyRequired = replyRequired; - try { - os.reset(); - os.writeObject(req); - if (replyRequired) { - reply = (EV3Reply) is.readObject(); - if (reply.e != null) throw new RemoteRequestException(reply.e); - } - return reply; - } catch (Exception e) { - throw new RemoteRequestException(e); - } - } - - class KeysListenThread extends Thread { - - public KeysListenThread() { - setDaemon(true); - } - - @Override - public void run() { - while (true) { - int state = RemoteRequestKeys.this.waitForAnyEvent(); - - int mask = 1; - for (int i=0;i T open(Class portclass) { - RemoteRequestIOPort p = null; - switch(typ) - { - case SENSOR_PORT: - if (portclass == RemoteRequestUARTPort.class || portclass == UARTPort.class) - p = new RemoteRequestUARTPort(is,os); - if (portclass == RemoteRequestAnalogPort.class || portclass == AnalogPort.class) - p = new RemoteRequestAnalogPort(is, os); - else if (portclass == RemoteRequestI2CPort.class|| portclass == I2CPort.class) - p = new RemoteRequestI2CPort(is, os); - break; - case MOTOR_PORT: - if (portclass == BasicMotorPort.class) - p = new RemoteRequestMotorPort(is, os); - else if (portclass == TachoMotorPort.class) - p = new RemoteRequestMotorPort(is, os); - // TODO: Should we also allow Encoder? - break; - } - if (p == null) - throw new IllegalArgumentException("Invalid port interface"); - if (!p.open(typ, portNum, this)) - throw new DeviceException("unable to open port"); - return portclass.cast(p); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestRegulatedMotor.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestRegulatedMotor.java deleted file mode 100644 index f17c63d..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestRegulatedMotor.java +++ /dev/null @@ -1,247 +0,0 @@ -package lejos.remote.ev3; - -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; - -public class RemoteRequestRegulatedMotor implements RegulatedMotor { - private ObjectInputStream is; - private ObjectOutputStream os; - private int portNum; - - public RemoteRequestRegulatedMotor(ObjectInputStream is, - ObjectOutputStream os, String portName, char motorType) { - this.is = is; - this.os = os; - portNum = portName.charAt(0) - 'A'; - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.CREATE_REGULATED_MOTOR; - req.str = portName; - req.ch = motorType; - sendRequest(req, false); - } - - @Override - public void forward() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_FORWARD; - sendRequest(req, false); - } - - @Override - public void backward() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_BACKWARD; - sendRequest(req, false); - } - - @Override - public void stop() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_STOP; - sendRequest(req, true); - } - - @Override - public void flt() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_FLT; - sendRequest(req, true); - } - - @Override - public boolean isMoving() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_IS_MOVING; - return sendRequest(req, true).result; - } - - @Override - public int getRotationSpeed() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_GET_ROTATION_SPEED; - return sendRequest(req, true).reply; - } - - @Override - public int getTachoCount() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_GET_TACHO_COUNT; - return sendRequest(req, true).reply; - } - - @Override - public void resetTachoCount() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_RESET_TACHO_COUNT;; - sendRequest(req, false); - } - - @Override - public void addListener(RegulatedMotorListener listener) { - // TODO Auto-generated method stub - } - - @Override - public RegulatedMotorListener removeListener() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void stop(boolean immediateReturn) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_STOP_IMMEDIATE; - req.flag = immediateReturn; - sendRequest(req, !immediateReturn); - } - - @Override - public void flt(boolean immediateReturn) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_FLT_IMMEDIATE; - req.flag = immediateReturn; - sendRequest(req, !immediateReturn); - } - - @Override - public void waitComplete() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_WAIT_COMPLETE; - sendRequest(req, true); - } - - @Override - public void rotate(int angle, boolean immediateReturn) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_ROTATE_IMMEDIATE; - req.intValue2 = angle; - req.flag = immediateReturn; - sendRequest(req, !immediateReturn); - } - - @Override - public void rotate(int angle) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_ROTATE; - req.intValue2 = angle; - sendRequest(req, true); - } - - @Override - public void rotateTo(int limitAngle) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_ROTATE_TO; - req.intValue2 = limitAngle; - sendRequest(req, true); - } - - @Override - public void rotateTo(int limitAngle, boolean immediateReturn) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_ROTATE_TO_IMMEDIATE; - req.intValue2 = limitAngle; - req.flag = immediateReturn; - sendRequest(req, !immediateReturn); - } - - @Override - public int getLimitAngle() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_GET_LIMIT_ANGLE; - return sendRequest(req, true).reply; - } - - @Override - public void setSpeed(int speed) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_SET_SPEED; - req.intValue2 = speed; - sendRequest(req, false); - } - - @Override - public int getSpeed() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_GET_SPEED; - return sendRequest(req, true).reply; - } - - @Override - public float getMaxSpeed() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_GET_MAX_SPEED; - return sendRequest(req, true).floatReply; - } - - @Override - public boolean isStalled() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_IS_STALLED; - return sendRequest(req, true).result; - } - - @Override - public void setStallThreshold(int error, int time) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_SET_STALL_THRESHOLD; - req.intValue2 = error; - req.intValue3 = time; - sendRequest(req, false); - } - - @Override - public void setAcceleration(int acceleration) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_SET_ACCELERATION; - req.intValue2 = acceleration; - sendRequest(req, false); - } - - @Override - public void close() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.MOTOR_CLOSE; - sendRequest(req, true); - } - - private EV3Reply sendRequest(EV3Request req, boolean replyRequired) { - EV3Reply reply = null; - req.replyRequired = replyRequired; - req.intValue = portNum; - try { - os.reset(); - os.writeObject(req); - if (replyRequired) { - reply = (EV3Reply) is.readObject(); - if (reply.e != null) throw new RemoteRequestException(reply.e); - } - return reply; - } catch (Exception e) { - throw new RemoteRequestException(e); - } - } - - @Override - public void synchronizeWith(RegulatedMotor[] syncList) - { - // TODO Auto-generated method stub - - } - - @Override - public void startSynchronization() - { - // TODO Auto-generated method stub - - } - - @Override - public void endSynchronization() - { - // TODO Auto-generated method stub - - } -} diff --git a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestSampleProvider.java b/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestSampleProvider.java deleted file mode 100644 index 9349066..0000000 --- a/ev3classes/src/main/java/lejos/remote/ev3/RemoteRequestSampleProvider.java +++ /dev/null @@ -1,79 +0,0 @@ -package lejos.remote.ev3; - -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import lejos.robotics.SampleProvider; - -public class RemoteRequestSampleProvider implements SampleProvider { - private ObjectInputStream is; - private ObjectOutputStream os; - private int portNum; - - public RemoteRequestSampleProvider(ObjectInputStream is, - ObjectOutputStream os, String portName, String sensorName, String modeName) { - this.is = is; - this.os = os; - portNum = portName.charAt(1) - '1'; - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.CREATE_SAMPLE_PROVIDER; - req.str = sensorName; - req.str2 = portName; - req.str3 = modeName; - sendRequest(req, true); - } - - public RemoteRequestSampleProvider(ObjectInputStream is, - ObjectOutputStream os, String portName, String sensorName, String modeName, String topic, float frequency) { - this.is = is; - this.os = os; - portNum = portName.charAt(1) - '1'; - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.CREATE_SAMPLE_PROVIDER_PUBLISH; - req.str = sensorName; - req.str2 = portName; - req.str3 = modeName; - req.str4 = topic; - req.floatValue = frequency; - sendRequest(req, true); - } - - @Override - public int sampleSize() { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.SAMPLE_SIZE; - return sendRequest(req, true).reply; - } - - @Override - public void fetchSample(float[] sample, int offset) { - EV3Request req = new EV3Request(); - req.request = EV3Request.Request.FETCH_SAMPLE; - req.replyRequired = true; - EV3Reply reply = sendRequest(req, true); - for(int i=0;i 2) { - for(int i=0;i> 8); - socket.write(header,0,2); - } - socket.write(buffer, 0, numBytes); - return 0; - } - - @Override - public int read(byte[] buf, int length, boolean b) { - if (eof) return -1; - try { - //System.out.println("Reading with wait = " + b); - if (mode != NXTConnection.RAW) { - int len = socket.read(buffer, length); - //System.out.println("Read " + len + " bytes"); - if (len > 2) { - for(int i=0;i devices = Bluetooth.getLocalDevice().search(); - RemoteBTDevice btDevice = null; - - if (devices == null) return null; - - for(RemoteBTDevice device: devices) { - - if (target == null || target.length() == 0 || target.equals("*")) { - btDevice = device; - break; - } else if (device.getName().equals(target)) { - btDevice = device; - break; - } - } - - if (btDevice == null) return null; - - for(int i=0;i<6;i++) { - sa.bd_addr[i] = btDevice.getDeviceAddress()[i]; - } - - socket.connect(sa, sa.size()); - - return new BTConnection(socket, mode); - - } catch (BluetoothException e) { - System.err.println("Error getting remote devices: " + e); - return null; - } - } - } - - @Override - public BTConnection waitForConnection(int timeout, int mode) { - NativeSocket.SockAddr sa = new NativeSocket.SockAddr(); - - socket.bind(sa, sa.size()); - - socket.listen(1); - - NativeSocket client = socket.accept(); - return new BTConnection(client, mode); - } - - @Override - public boolean cancel() { - // TODO Auto-generated method stub - return false; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/Connection.java b/ev3classes/src/main/java/lejos/remote/nxt/Connection.java deleted file mode 100644 index 6b26c32..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/Connection.java +++ /dev/null @@ -1,7 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -public interface Connection { - public void close() throws IOException; -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/DeviceInfo.java b/ev3classes/src/main/java/lejos/remote/nxt/DeviceInfo.java deleted file mode 100644 index 0c79f23..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/DeviceInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package lejos.remote.nxt; - -/** - * Represents a remote NXT accessed via LCP. - * - */ -public class DeviceInfo { - public byte status; - public String NXTname; - public String bluetoothAddress; - public int signalStrength; - public int freeFlash; -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/ErrorMessages.java b/ev3classes/src/main/java/lejos/remote/nxt/ErrorMessages.java deleted file mode 100644 index 745710a..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/ErrorMessages.java +++ /dev/null @@ -1,196 +0,0 @@ -package lejos.remote.nxt; - -/** - * Error messages that can be returned after a call to the NXT brick. - * e.g. The return value comes from method calls like Motor.backward(), - * SoundSensor.playTone(), etc... Actual values are only returned if you enable - * validation in the NXT class using NXT.setValidation(). - * - * @author Brian Bagnall - * - */ -public class ErrorMessages { - - private ErrorMessages() { - // class cannot be instantiated - } - - // leJOS specific error codes, TODO delete and replace with standard codes - public static final byte NOT_IMPLEMENTED = (byte) 0xFD; - public static final byte DIRECTORY_FULL = (byte) 0xFC; - - // Direct command errors: - public static final byte PENDING_COMMUNICATION_TRANSACTION_IN_PROGRESS = 0x20; - public static final byte SPECIFIED_MAILBOX_QUEUE_IS_EMPTY = 0x40; - /** Request failed (i.e. specified file not found) */ - public static final byte REQUEST_FAILED = (byte)0xBD; - public static final byte UNKNOWN_COMMAND_OPCODE = (byte)0xBE; - public static final byte INSANE_PACKET = (byte)0xBF; - public static final byte DATA_CONTAINS_OUT_OF_RANGE_VALUES = (byte)0xC0; - public static final byte COMMUNICATION_BUS_ERROR = (byte)0xDD; - public static final byte NO_FREE_MEMORY_IN_COMMUNICATION_BUFFER = (byte)0xDE; - /** Specified channel/connection is not valid */ - public static final byte SPECIFIED_CHANNEL_CONNECTION_IS_NOT_VALID = (byte)0xDF; - /** Specified channel/connection not configured or busy */ - public static final byte SPECIFIED_CHANNEL_CONNECTION_NOT_CONFIGURED_OR_BUSY = (byte)0xE0; - public static final byte NO_ACTIVE_PROGRAM = (byte)0xEC; - public static final byte ILLEGAL_SIZE_SPECIFIED = (byte)0xED; - public static final byte ILLEGAL_MAILBOX_QUEUE_ID_SPECIFIED = (byte)0xEE; - public static final byte ATTEMPTED_TO_ACCESS_INVALID_FIELD_OF_A_STRUCTURE = (byte)0xEF; - public static final byte BAD_INPUT_OR_OUTPUT_SPECIFIED = (byte)0xF0; - public static final byte INSUFFICIENT_MEMORY_AVAILABLE = (byte)0xFB; - public static final byte BAD_ARGUMENTS = (byte)0xFF; - - // System command errors: - public static final byte SUCCESS = 0x00; - public static final byte NO_MORE_HANDLES = (byte)0x81; - public static final byte NO_SPACE = (byte)0x82; - public static final byte NO_MORE_FILES = (byte)0x83; - public static final byte END_OF_FILE_EXPECTED = (byte)0x84; - public static final byte END_OF_FILE = (byte)0x85; - public static final byte NOT_A_LINEAR_FILE = (byte)0x86; - public static final byte FILE_NOT_FOUND = (byte)0x87; - public static final byte HANDLE_ALREADY_CLOSED = (byte)0x88; - public static final byte NO_LINEAR_SPACE = (byte)0x89; - public static final byte UNDEFINED_ERROR = (byte)0x8A; - public static final byte FILE_IS_BUSY = (byte)0x8B; - public static final byte NO_WRITE_BUFFERS = (byte)0x8C; - public static final byte APPEND_NOT_POSSIBLE = (byte)0x8D; - public static final byte FILE_IS_FULL = (byte)0x8E; - public static final byte FILE_EXISTS = (byte)0x8F; - public static final byte MODULE_NOT_FOUND = (byte)0x90; - public static final byte OUT_OF_BOUNDARY = (byte)0x91; - public static final byte ILLEGAL_FILE_NAME = (byte)0x92; - public static final byte ILLEGAL_HANDLE = (byte)0x93; - - public static String lcpErrorToString(byte error) - { - String s; - switch (error) - { - // leJOS specific codes: - case DIRECTORY_FULL: - s = "Directory full"; - break; - case NOT_IMPLEMENTED: - s = "Not implemented"; - break; - - // direct command errors: - case PENDING_COMMUNICATION_TRANSACTION_IN_PROGRESS: - s = "Pending communication transaction in progress"; - break; - case SPECIFIED_MAILBOX_QUEUE_IS_EMPTY: - s = "Specified mailbox is empty"; - break; - case REQUEST_FAILED: - s = "Request failed"; - break; - case UNKNOWN_COMMAND_OPCODE: - s = "Unknown command opcode"; - break; - case INSANE_PACKET: - s = "Insane packet"; - break; - case DATA_CONTAINS_OUT_OF_RANGE_VALUES: - s = "Data contains out-of-range values"; - break; - case COMMUNICATION_BUS_ERROR: - s = "Communication bus error"; - break; - case NO_FREE_MEMORY_IN_COMMUNICATION_BUFFER: - s = "No free memory in communication buffer"; - break; - case SPECIFIED_CHANNEL_CONNECTION_IS_NOT_VALID: - s = "Specified channel/configuration is not valid"; - break; - case SPECIFIED_CHANNEL_CONNECTION_NOT_CONFIGURED_OR_BUSY: - s = "Specified channel/configuration not configured or busy"; - break; - case NO_ACTIVE_PROGRAM: - s = "No active program"; - break; - case ILLEGAL_SIZE_SPECIFIED: - s = "Illegal size specified"; - break; - case ILLEGAL_MAILBOX_QUEUE_ID_SPECIFIED: - s = "Illegal mailbox queue ID specified"; - break; - case ATTEMPTED_TO_ACCESS_INVALID_FIELD_OF_A_STRUCTURE: - s = "Attempted to access invalid field of a structure"; - break; - case BAD_INPUT_OR_OUTPUT_SPECIFIED: - s = "Bad input or output specified"; - break; - case INSUFFICIENT_MEMORY_AVAILABLE: - s = "Insufficient memory available"; - break; - case BAD_ARGUMENTS: - s = "Bad arguments"; - break; - - // system command errors: - case NO_MORE_HANDLES: - s = "No more handles"; - break; - case NO_SPACE: - s = "No space"; - break; - case NO_MORE_FILES: - s = "No more files"; - break; - case END_OF_FILE_EXPECTED: - s = "End of file expected"; - break; - case END_OF_FILE: - s = "End of file"; - break; - case NOT_A_LINEAR_FILE: - s = "Not a linear file"; - break; - case FILE_NOT_FOUND: - s = "File not found"; - break; - case HANDLE_ALREADY_CLOSED: - s = "Handle already closed"; - break; - case NO_LINEAR_SPACE: - s = "No linear space"; - break; - case UNDEFINED_ERROR: - s = "Undefined error"; - break; - case FILE_IS_BUSY: - s = "File is busy"; - break; - case NO_WRITE_BUFFERS: - s = "No write buffers"; - break; - case APPEND_NOT_POSSIBLE: - s = "Append not possible"; - break; - case FILE_IS_FULL: - s = "File is full"; - break; - case FILE_EXISTS: - s = "File exists"; - break; - case MODULE_NOT_FOUND: - s = "Module not found"; - break; - case OUT_OF_BOUNDARY: - s = "Out of boundary"; - break; - case ILLEGAL_FILE_NAME: - s = "Illegal file name"; - break; - case ILLEGAL_HANDLE: - s = "Illegal handle"; - break; - default: - s = "Unknown error code ("+(error & 0xFF)+")"; - break; - } - return s; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/FileInfo.java b/ev3classes/src/main/java/lejos/remote/nxt/FileInfo.java deleted file mode 100644 index 4615175..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/FileInfo.java +++ /dev/null @@ -1,27 +0,0 @@ -package lejos.remote.nxt; - -/** - * Structure that gives information about a leJOS NXJ file. - * - */ -public class FileInfo { - - /** - * The name of the file - up to 20 characters. - */ - public String fileName; - - /** - * The handle for accessing the file. - */ - public byte fileHandle; - - /** - * The size of the file in bytes. - */ - public int fileSize; - - public FileInfo(String fileName) { - this.fileName = fileName; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/FirmwareInfo.java b/ev3classes/src/main/java/lejos/remote/nxt/FirmwareInfo.java deleted file mode 100644 index 211fbe6..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/FirmwareInfo.java +++ /dev/null @@ -1,11 +0,0 @@ -package lejos.remote.nxt; - -/** - * Firmware information for a remote NXT accessed via LCP. - * - */ -public class FirmwareInfo { - public byte status; - public String protocolVersion; - public String firmwareVersion; -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/remote/nxt/InputConnection.java b/ev3classes/src/main/java/lejos/remote/nxt/InputConnection.java deleted file mode 100644 index a62e784..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/InputConnection.java +++ /dev/null @@ -1,18 +0,0 @@ -package lejos.remote.nxt; - -import java.io.*; - -public interface InputConnection extends Connection { - /** - * Open and return a data input stream for a connection. - * @return the data input stream - */ - public DataInputStream openDataInputStream(); - - /** - * Open and return an input stream for a connection. - * @return the input stream - */ - public InputStream openInputStream(); - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/InputValues.java b/ev3classes/src/main/java/lejos/remote/nxt/InputValues.java deleted file mode 100644 index b73c32d..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/InputValues.java +++ /dev/null @@ -1,38 +0,0 @@ -package lejos.remote.nxt; - -/** - * Sensor input values for a remote NXT accessed via LCP. - * - * @author Brian Bagnall - * - */ -public class InputValues { - public int inputPort; - /** - * NXT indicates if it thinks the data is valid - */ - public boolean valid = true; - public boolean isCalibrated; - public int sensorType; - public int sensorMode; - /** - * The raw value from the Analog to Digital (AD) converter. - */ - public int rawADValue; - /** - * The normalized value from the Analog to Digital (AD) converter. I really don't - * know for sure which values are normalized yet. - * 0 to 1023 - */ - public int normalizedADValue; - /** - * The scaled value starts working after the first call to the sensor. - * The first value will be the raw value, but after that it produces scaled values. - * With the touch sensor, off scales to 0 and on scales to 1. - */ - public short scaledValue; - /** - * Currently unused. - */ - public short calibratedValue; -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/LCP.java b/ev3classes/src/main/java/lejos/remote/nxt/LCP.java deleted file mode 100644 index 4f68b31..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/LCP.java +++ /dev/null @@ -1,729 +0,0 @@ -package lejos.remote.nxt; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; - -import lejos.hardware.BrickFinder; -import lejos.hardware.Button; -import lejos.hardware.Keys; -import lejos.hardware.Sound; -import lejos.hardware.motor.Motor; -import lejos.hardware.motor.NXTRegulatedMotor; -import lejos.hardware.port.Port; -import lejos.hardware.port.SensorPort; -import lejos.internal.io.Settings; -import lejos.internal.io.SystemSettings; - -/** - * - * Implements the Lego Communication Protocol, - * with some extensions for lejos NXJ. - * - */ -public class LCP { - private static byte[] i2cBuffer = new byte[16]; - private static File[] files = null; - private static String[] fileNames = null; - private static int fileIdx = -1; - private static String currentProgram = null; - private static File file = null; - private static FileOutputStream out = null; - private static FileInputStream in = null; - private static int numFiles; - private static char[] charBuffer = new char[20]; - //public static InBox[] inBoxes = new InBox[20]; - - // Command types constants. Indicates type of packet being sent or received. - public static final byte DIRECT_COMMAND_REPLY = 0x00; - public static final byte SYSTEM_COMMAND_REPLY = 0x01; - public static final byte REPLY_COMMAND = 0x02; - public static final byte DIRECT_COMMAND_NOREPLY = (byte)0x80; // Avoids ~100ms latency - public static final byte SYSTEM_COMMAND_NOREPLY = (byte)0x81; // Avoids ~100ms latency - - // Direct Commands - public static final byte START_PROGRAM = 0x00; - public static final byte STOP_PROGRAM = 0x01; - public static final byte PLAY_SOUND_FILE = 0x02; - public static final byte PLAY_TONE = 0x03; - public static final byte SET_OUTPUT_STATE = 0x04; - public static final byte SET_INPUT_MODE = 0x05; - public static final byte GET_OUTPUT_STATE = 0x06; - public static final byte GET_INPUT_VALUES = 0x07; - public static final byte RESET_SCALED_INPUT_VALUE = 0x08; - public static final byte MESSAGE_WRITE = 0x09; - public static final byte RESET_MOTOR_POSITION = 0x0A; - public static final byte GET_BATTERY_LEVEL = 0x0B; - public static final byte STOP_SOUND_PLAYBACK = 0x0C; - public static final byte KEEP_ALIVE = 0x0D; - public static final byte LS_GET_STATUS = 0x0E; - public static final byte LS_WRITE = 0x0F; - public static final byte LS_READ = 0x10; - public static final byte GET_CURRENT_PROGRAM_NAME = 0x11; - public static final byte MESSAGE_READ = 0x13; - - // NXJ additions - public static final byte NXJ_DISCONNECT = 0x20; - public static final byte NXJ_DEFRAG = 0x21; - public static final byte NXJ_SET_DEFAULT_PROGRAM = 0x22; - public static final byte NXJ_SET_SLEEP_TIME = 0x23; - public static final byte NXJ_SET_VOLUME = 0x24; - public static final byte NXJ_SET_KEY_CLICK_VOLUME = 0x25; - public static final byte NXJ_SET_AUTO_RUN = 0x26; - public static final byte NXJ_GET_VERSION = 0x27; - public static final byte NXJ_GET_DEFAULT_PROGRAM = 0x28; - public static final byte NXJ_GET_SLEEP_TIME = 0x29; - public static final byte NXJ_GET_VOLUME = 0x2A; - public static final byte NXJ_GET_KEY_CLICK_VOLUME = 0x2B; - public static final byte NXJ_GET_AUTO_RUN = 0x2C; - - // System Commands: - public static final byte OPEN_READ = (byte)0x80; - public static final byte OPEN_WRITE = (byte)0x81; - public static final byte READ = (byte)0x82; - public static final byte WRITE = (byte)0x83; - public static final byte CLOSE = (byte)0x84; - public static final byte DELETE = (byte)0x85; - public static final byte FIND_FIRST = (byte)0x86; - public static final byte FIND_NEXT = (byte)0x87; - public static final byte GET_FIRMWARE_VERSION = (byte)0x88; - public static final byte OPEN_WRITE_LINEAR = (byte)0x89; - public static final byte OPEN_READ_LINEAR = (byte)0x8A; - public static final byte OPEN_WRITE_DATA = (byte)0x8B; - public static final byte OPEN_APPEND_DATA = (byte)0x8C; - public static final byte BOOT = (byte)0x97; - public static final byte SET_BRICK_NAME = (byte)0x98; - public static final byte GET_DEVICE_INFO = (byte)0x9B; - public static final byte DELETE_USER_FLASH = (byte)0xA0; - public static final byte POLL_LENGTH = (byte)0xA1; - public static final byte POLL = (byte)0xA2; - - public static final byte NXJ_PACKET_MODE = (byte)0xff; - - // System settings - - private static final String defaultProgramProperty = "lejos.default_program"; - private static final String sleepTimeProperty = "lejos.sleep_time"; - private static final String defaultProgramAutoRunProperty = "lejos.default_autoRun"; - private static final int defaultSleepTime = 2; - - private static byte menuMajorVersion = 0; - private static byte menuMinorVersion = 0; - private static byte menuPatchLevel = 0; - private static int menuRevision = 0; - - private static LCPMessageListener listener = null; - - private static Port[] PORTS = {SensorPort.S1, SensorPort.S2, SensorPort.S3, SensorPort.S4}; - - private LCP() - { - // Do not instantiate - all methods are static - } - - /** - * Add a listener for incoming LCP messages. - * Currently only one listener is supported. - * - * @param aListener the LCP message listener - */ - public static void addMessageListener(LCPMessageListener aListener) { - listener = aListener; - } - - /** - * Emulates a Lego firmware Direct or System command - * @param cmd the buffer containing the command - * @param cmdLen the length of the command - */ - public static int emulateCommand(byte[] cmd, int cmdLen, byte[] reply) - { - final byte cmdId = cmd[1]; - - reply[0] = REPLY_COMMAND; - reply[1] = cmdId; - for(int i=2; i0) m.forward(); - else m.backward(); - } - - if (motorid >= 0) break; - } - break; - } - case RESET_MOTOR_POSITION: { - // Check if boolean value (cmd[3]) is false. If so, - // reset TachoCount (i.e. RotationCount in LEGO FW terminology) - // Note we assume that this like all other LCP motor commands needs to operate on - // a regulated motor. - if (cmd[3] == 0) - { - byte port = cmd[2]; - NXTRegulatedMotor m = Motor.A; - m.resetTachoCount(); - } - break; - } - case KEEP_ALIVE: { - len = 7; - break; - } - case LS_WRITE: { - byte port = cmd[2]; - byte txLen = cmd[3]; - byte rxLen = cmd[4]; - //SensorPort p = SensorPort.getInstance(port); - //p.i2cEnable(I2CPort.LEGO_MODE); - //p.i2cStart(cmd[5], cmd, 6, txLen-1, rxLen); - //p.i2cWaitIOComplete(); - break; - } - case LS_READ: { - byte port = cmd[2]; - //SensorPort p = SensorPort.getInstance(port); - int ret = 0; // p.i2cComplete(i2cBuffer, 0, i2cBuffer.length); - if (ret < 0) { - // not sure whether that is correct - reply[2] = ErrorMessages.COMMUNICATION_BUS_ERROR; - reply[3] = 0; - } else { - reply[2] = ErrorMessages.SUCCESS; - reply[3] = (byte) ret; - System.arraycopy(i2cBuffer, 0, reply, 4, ret); - } - len = 20; - break; - } - case LS_GET_STATUS: { - byte port = cmd[2]; - //SensorPort p = SensorPort.getInstance(port); - // TODO which status code to return? 0 and 1 seem to arbitrary choices - //reply[2] = (byte)(p.i2cStatus() == 0 ? 0 : 1); - // TODO reply[3] = number of bytes ready to read - len = 4; - break; - } - case OPEN_READ: { - initFiles(); - file = new File(getFile(cmd,2)); - try { - in = new FileInputStream(file); - int size = (int) file.length(); - setReplyInt(size,reply,4); - } catch (Exception e) { - reply[2] = ErrorMessages.FILE_NOT_FOUND; - } - len = 8; - break; - } - case OPEN_WRITE: { - int size = getInt(cmd, 22); - initFiles(); - - // If insufficient flash memory, report an error - if (size > 0) { //File.freeMemory()) { - reply[2] = ErrorMessages.INSUFFICIENT_MEMORY_AVAILABLE; - } else { - try { - file = new File(getFile(cmd,2)); - //TODO lego firmware reports error in case file exists - if (file.exists()) { - file.delete(); - numFiles--; - } - - file.createNewFile(); - fileNames = new String[++numFiles]; - for(int j=0;j= fileNames.length) reply[2] = ErrorMessages.FILE_NOT_FOUND; - else - { - for(int i=0;i 58 ? 58 : msgLen); - for(int i=0;i<58 && i= 0 && volume <= 100) { - Sound.setVolume(volume); - Settings.setProperty(Sound.VOL_SETTING, String.valueOf(volume)); - } - break; - } - case NXJ_SET_KEY_CLICK_VOLUME: { - int volume = cmd[2]; - if (volume >= 0 && volume <= 100) { - Button.setKeyClickVolume(volume); - Settings.setProperty(Keys.VOL_SETTING, String.valueOf(volume)); - } - break; - } - case NXJ_GET_VERSION: { - //reply[3] = (byte) NXT.getFirmwareMajorVersion(); - //reply[4] = (byte) NXT.getFirmwareMinorVersion(); - //reply[5] = (byte) NXT.getFirmwarePatchLevel(); - //setReplyInt(NXT.getFirmwareRevision(), reply, 6); - reply[10] = menuMajorVersion; - reply[11] = menuMinorVersion; - reply[12] = menuPatchLevel; - setReplyInt(menuRevision, reply, 13); - len = 17; - break; - } - case NXJ_GET_VOLUME: { - reply[3] = (byte) Sound.getVolume(); - len = 4; - break; - } - case NXJ_GET_KEY_CLICK_VOLUME: { - reply[3] = (byte) Button.getKeyClickVolume(); - len = 4; - break; - } - case NXJ_GET_SLEEP_TIME: { - reply[3] = (byte) SystemSettings.getIntSetting(sleepTimeProperty, defaultSleepTime); - len = 4; - break; - } - case NXJ_GET_AUTO_RUN: { - String autoRun = SystemSettings.getStringSetting(defaultProgramAutoRunProperty, "OFF"); - reply[3] = (byte) (autoRun.equals("ON") ? 1 : 0); - len = 4; - break; - } - case NXJ_GET_DEFAULT_PROGRAM: { - String name = SystemSettings.getStringSetting(defaultProgramProperty, ""); - for(int i=0;i> 8) & 0xFF); - } - - private static byte getMSB1(int i) - { - return (byte) ((i >> 16) & 0xFF); - } - - private static byte getMSB2(int i) - { - return (byte) ((i >> 24) & 0xFF); - } - - private static void setReplyInt(int n, byte [] reply, int start) { - reply[start] = getLSB(n); - reply[start+1] = getMSB(n); - reply[start+2] = getMSB1(n); - reply[start+3] = getMSB2(n); - } - - private static void setReplyShortInt(int n, byte [] reply, int start) { - reply[start] = getLSB(n); - reply[start+1] = getMSB(n); - } - - private static void initFiles() { - if (files == null) { - files = new File("/home/lejos/programs").listFiles(); - numFiles = 0; - for(int i=0;i> 16) & 0xFF); - menuMinorVersion = (byte) ((version >> 8) & 0xFF); - menuPatchLevel = (byte) (version & 0xFF); - menuRevision = revision; - } - -} - diff --git a/ev3classes/src/main/java/lejos/remote/nxt/LCPException.java b/ev3classes/src/main/java/lejos/remote/nxt/LCPException.java deleted file mode 100644 index cbc6808..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/LCPException.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -public class LCPException extends IOException -{ - private byte errorcode; - - public LCPException() { - super(); - } - - public LCPException(String s) { - super(s); - } - - public LCPException(byte errorcode) { - this(ErrorMessages.lcpErrorToString(errorcode)); - this.errorcode = errorcode; - } - - public LCPException(String s, Throwable cause) { - this(s); - this.initCause(cause); - } - - /** - * Returns error code, if this exception was caused by the NXT returned an LCP error. - * @return non-zero balue of there the NXT provided an error code or zero otherwise. - */ - public byte getErrorcode() { - return this.errorcode; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/LCPMessageListener.java b/ev3classes/src/main/java/lejos/remote/nxt/LCPMessageListener.java deleted file mode 100644 index d57519a..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/LCPMessageListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package lejos.remote.nxt; - -public interface LCPMessageListener { - - public void messageReceived(byte inBox, String message); -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/LCPResponder.java b/ev3classes/src/main/java/lejos/remote/nxt/LCPResponder.java deleted file mode 100644 index 6366e6c..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/LCPResponder.java +++ /dev/null @@ -1,133 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -/** - * Support for LCP commands - * - * @author Lawrie Griffiths/Andy Shaw - * - */ -public class LCPResponder extends Thread { - protected NXTCommConnector connector = null; - protected NXTConnection conn = null; - protected boolean running = true; - - /** - * Create a Responder using the provided connector - * The connector is used to create the listening connection used to accept - * remote commands. - * @param connector - */ - public LCPResponder(NXTCommConnector connector) - { - this.connector = connector; - } - - /** - * Method called when the responder is waiting for a new connection. - * Default action is to wait for the new connection and return. - */ - protected synchronized void waitConnect() - { - while (running && (conn = connector.waitForConnection(0, NXTConnection.LCP)) == null) - try{wait(50);}catch(Exception e){ - // Ignore exception - } - } - - /** - * Method called to disconnect the responder connect. - * Default action is to close the underlying connection object. - */ - protected synchronized void disconnect() - { - if (conn != null) - try { - conn.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - conn = null; - } - - /** - * Method called with a newly read command, before it is processed. - * Default action is to detect invalid commands and if detected to drop the - * connection. - * @param inMsg Newly read command - * @param len length of the command - * @return the length of the command - */ - protected int preCommand(byte[] inMsg, int len) - { - if (len < 0 || inMsg[1] == LCP.START_PROGRAM) - disconnect(); - return len; - } - - /** - * Process the actual command - * Default action is to call the LCP object to emulate the command - * @param inMsg The command bytes - * @param len length of the command - * @param reply bytes to send back in response to the command - * @return length of the reply - */ - protected int command(byte[] inMsg, int len, byte[] reply) - { - return LCP.emulateCommand(inMsg, len, reply); - } - - protected void postCommand(byte[] inMsg, int inLen, byte[] replyMsg, int replyLen) - { - if (inMsg[1] == LCP.NXJ_DISCONNECT) - disconnect(); - } - - @Override - public void run() - { - byte[] inMsg = new byte[64]; - byte [] reply = new byte[64]; - int len; - - while (running) - { - waitConnect(); - while (conn != null) - { - len = conn.read(inMsg,64); - len = preCommand(inMsg, len); - if (len > 0) - { - int replyLen = command(inMsg,len, reply); - if ((inMsg[0] & 0x80) == 0 && replyLen > 0) conn.write(reply, replyLen); - postCommand(inMsg, len, reply, replyLen); - } - Thread.yield(); - } - } - } - - /** - * Terminate the responder. Abort any listening operation and close - * any open connections (this will also abort any current read requests). - */ - public void shutdown() - { - running = false; - connector.cancel(); - if (conn != null) disconnect(); - } - - /** - * Checks whether there is an active connection - * - * @return true iff the responder is connected - */ - public boolean isConnected() { - return (conn != null); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXJFirmwareInfo.java b/ev3classes/src/main/java/lejos/remote/nxt/NXJFirmwareInfo.java deleted file mode 100644 index 65d4271..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXJFirmwareInfo.java +++ /dev/null @@ -1,36 +0,0 @@ -package lejos.remote.nxt; - -/** - * Information about leJOS NXJ firmware and menu - * - * @author Lawrie Griffiths - * - */ -public class NXJFirmwareInfo { - public byte firmwareMajorVersion; - public byte firmwareMinorVersion; - public byte firmwarePatchLevel; - public int firmwareRevision; - public byte menuMajorVersion; - public byte menuMinorVersion; - public byte menuPatchLevel; - public int menuRevision; - - /** - * Get the full firmware version - * - * @return the firmware version as a string - */ - public String getFirmwareVersion() { - return firmwareMajorVersion + "." + firmwareMinorVersion + "." + firmwarePatchLevel + "(" + firmwareRevision + ")"; - } - - /** - * Get the full firmware version - * - * @return the firmware version as a string - */ - public String getMenuVersion() { - return menuMajorVersion + "." + menuMinorVersion + "." + menuPatchLevel + "(" + menuRevision + ")"; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXT.java b/ev3classes/src/main/java/lejos/remote/nxt/NXT.java deleted file mode 100644 index 195659d..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXT.java +++ /dev/null @@ -1,8 +0,0 @@ -package lejos.remote.nxt; - -import lejos.hardware.Brick; - -public interface NXT extends Brick -{ - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTComm.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTComm.java deleted file mode 100644 index 9061954..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTComm.java +++ /dev/null @@ -1,57 +0,0 @@ -package lejos.remote.nxt; - -import java.io.*; - -/** - * - * Initiates communication to a remote NXT. Used by NXTCommand - * to implement the Lego Communications Protocol (LCP) over Bluetooth. - * - */ -public class NXTComm implements NXTCommRequest { - private NXTConnection con; - private NXTCommConnector connector; - byte[] buf = new byte[64]; - - /** - * Create an NXTComm object and define what type of communications it should - * use by specifying the appropriate connector object. - * @param connector - */ - NXTComm(NXTCommConnector connector) - { - this.connector = connector; - } - - public boolean open(String name, int mode) throws IOException { - con = connector.connect(name, mode); - if (con == null) return false; - - return true; - } - - private void sendData(byte [] data) throws IOException { - if (con.write(data, data.length) < 0) throw new IOException(); - } - - private byte[] readData() throws IOException { - int len = 0; - - while (len == 0) len = con.read(buf, buf.length); - if (len < 0) throw new IOException(); - byte [] data = new byte[len]; - System.arraycopy(buf, 0, data, 0, len); - return data; - - } - - public byte[] sendRequest(byte [] message, int replyLen) throws IOException { - sendData(message); - if (replyLen == 0) return new byte[0]; - return readData(); - } - - public void close() throws IOException { - con.close(); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTCommConnector.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTCommConnector.java deleted file mode 100644 index 2f2662a..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTCommConnector.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.remote.nxt; - -/** - * Standard interface to connect/wait for a connection. - * @author andy - */ -public abstract class NXTCommConnector { - /** - * Open a connection to the specified name/address using the given I/O mode - * @param target The name or address of the device/host to connect to. - * @param mode The I/O mode to use for this connection - * @return A NXTConnection object for the new connection or null if error. - */ - public abstract NXTConnection connect(String target, int mode); - - /** - * Wait for an incoming connection, or for the request to timeout. - * @param timeout Time in ms to wait for the connection to be made - * @param mode I/O mode to be used for the accepted connection. - * @return A NXTConnection object for the new connection or null if error. - */ - public abstract NXTConnection waitForConnection(int timeout, int mode); - - /** - * Cancel a connection attempt. - * @return true if the connection attempt has been aborted. - */ - public abstract boolean cancel(); - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTCommDevice.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTCommDevice.java deleted file mode 100644 index 5100c6c..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTCommDevice.java +++ /dev/null @@ -1,170 +0,0 @@ -package lejos.remote.nxt; - -import lejos.internal.io.SystemSettings; - -/** - * Base class for nxt communications devices. Provides a common address/name, - * plus utility functions. - * @author andy - */ -abstract public class NXTCommDevice -{ - public static final int ADDRESS_LEN = 6; - public static final int NAME_LEN = 16; - public static final String SERIAL_NO = "lejos.usb_serno"; - public static final String NAME = "lejos.usb_name"; - - static String devAddress = "123"; - static String devName = "xxx"; - - static { - loadSettings(); - } - - /** - * Determine if a string contains a Bluetooth style address. - * @param s String to test - * @return true if the string is an address - */ - public static boolean isAddress(String s) - { - if (s == null || s.length() < 2) return false; - return s.charAt(0) == '0' && s.charAt(1) == '0'; - } - - - /** - * Convert a string version of a Bluetooth address into a byte array - * address. - * @param strAddress The string version of the address - * @return a byte array version of the address - */ - public static byte[] stringToAddress(String strAddress) - { - if (strAddress != null && strAddress.length() == (ADDRESS_LEN)*2) - { - // Convert to binary format - byte[] addr = new byte[ADDRESS_LEN]; - int out = 0; - for(int i = 0; i < strAddress.length(); i += 2) - { - char c = strAddress.charAt(i); - byte val = (byte)((c > '9' ? c - 'A' + 10 : c - '0') << 4); - c = strAddress.charAt(i+1); - val |= (byte)(c > '9' ? c - 'A' + 10 : c - '0'); - addr[out++] = val; - } - return addr; - } - else - return null; - } - - /** - * Convert the string version of a devName into a byte array. - * @param strName string version of the devName - * @return byte array containing the devName. - */ - public static byte[] stringToName(String strName) - { - if (strName != null && strName.length() <= NAME_LEN) - { - byte[] nam = new byte[NAME_LEN]; - for(int i = 0; i < strName.length(); i++) - { - nam[i] = (byte)strName.charAt(i); - } - return nam; - } - else - return null; - } - - protected static final char[] cs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - - /** - * Helper method to convert address byte array to String. - * @param addr A byte array of bytes containing the address. - * @return String representation of Bluetooth address. - */ - public static String addressToString(byte [] addr) - { - if (addr == null || addr.length < ADDRESS_LEN) return null; - char[] caddr = new char[ADDRESS_LEN*2]; - - int ci = 0; - int addri = 0; - - for(int i=0; i>> 8), - (byte) (size >>> 16), (byte) (size >>> 24) }; - request = appendBytes(request, fileLength); - byte[] reply = nxtComm.sendRequest(request, 4); - if (reply == null || reply.length != 4) { - throw new IOException("Invalid return from OPEN WRITE"); - } else if (reply[2] != ErrorMessages.SUCCESS) { - throw new LCPException(reply[2]); - } - return reply[3]; // The handle number - } - - /** - * Closes an open file. - * - * @param handle - * File handle number. - * @return Error code 0 = success - * @throws IOException - */ - public byte closeFile(byte handle) throws IOException { - byte[] request = { SYSTEM_COMMAND_NOREPLY, CLOSE, handle }; - return sendSystemRequest(request, 4); - } - - /** - * Delete a file on the NXT - * - * @param fileName the name of the file - * @return the error code 0 = success - * @throws IOException - */ - public byte delete(String fileName) throws IOException { - byte[] request = { SYSTEM_COMMAND_REPLY, DELETE }; - request = appendString(request, fileName); - return sendSystemRequest(request, 23); - } - - /** - * Find the first file on the NXT. - * - * @param wildCard - * [filename].[extension], *.[extension], [filename].*, *.* - * @return fileInfo object giving details of the file - */ - public FileInfo findFirst(String wildCard) throws IOException { - - byte[] request = { SYSTEM_COMMAND_REPLY, FIND_FIRST }; - request = appendString(request, wildCard); - - byte[] reply = nxtComm.sendRequest(request, 28); - FileInfo fileInfo = null; - if (reply[2] == 0 && reply.length == 28) { - StringBuffer name = new StringBuffer(new String(reply)) - .delete(0, 4); - int lastPos = name.indexOf("\0"); - if (lastPos < 0 || lastPos > 20) lastPos = 20; - name.delete(lastPos, name.length()); - fileInfo = new FileInfo(name.toString()); - fileInfo.fileHandle = reply[3]; - fileInfo.fileSize = (0xFF & reply[24]) | ((0xFF & reply[25]) << 8) - | ((0xFF & reply[26]) << 16) | ((0xFF & reply[27]) << 24); - } - return fileInfo; - } - - /** - * Find the next file on the NXT - * - * @param handle - * Handle number from the previous found file or from the Find - * First command. - * @return fileInfo object giving details of the file - */ - public FileInfo findNext(byte handle) throws IOException { - - byte[] request = { SYSTEM_COMMAND_REPLY, FIND_NEXT, handle }; - - byte[] reply = nxtComm.sendRequest(request, 28); - FileInfo fileInfo = null; - if (reply[2] == 0 && reply.length == 28) { - StringBuffer name = new StringBuffer(new String(reply)) - .delete(0, 4); - int lastPos = name.indexOf("\0"); - if (lastPos < 0 || lastPos > 20) lastPos = 20; - name.delete(lastPos, name.length()); - fileInfo = new FileInfo(name.toString()); - fileInfo.fileHandle = reply[3]; - fileInfo.fileSize = (0xFF & reply[24]) | ((0xFF & reply[25]) << 8) - | ((0xFF & reply[26]) << 16) | ((0xFF & reply[27]) << 24); - } - return fileInfo; - } - - /** - * Helper code to append a string and null terminator at the end of a - * command request. - * - * @param command the command - * @param str the string to append - * @return the concatenated command - */ - private byte[] appendString(byte[] command, String str) { - byte[] buff = new byte[command.length + str.length() + 1]; - for (int i = 0; i < command.length; i++) - buff[i] = command[i]; - for (int i = 0; i < str.length(); i++) - buff[command.length + i] = (byte) str.charAt(i); - buff[command.length + str.length()] = 0; - return buff; - } - - /** - * Helper method to concatenate two byte arrays - * @param array1 the first array (e.g. a request) - * @param array2 the second array (e.g. an extra parameter) - * - * @return the concatenated array - */ - private byte[] appendBytes(byte[] array1, byte[] array2) { - byte[] array = new byte[array1.length + array2.length]; - System.arraycopy(array1, 0, array, 0, array1.length); - System.arraycopy(array2, 0, array, array1.length, array2.length); - return array; - } - - /** - * Get the battery reading - * - * @return the battery level in millivolts - * @throws IOException - */ - public int getBatteryLevel() throws IOException { - byte[] request = { DIRECT_COMMAND_REPLY, GET_BATTERY_LEVEL }; - byte[] reply = nxtComm.sendRequest(request, 5); - int batteryLevel = (0xFF & reply[3]) | ((0xFF & reply[4]) << 8); - return batteryLevel; - } - - /** - * Call the close() command when your program ends, otherwise you will have - * to turn the NXT brick off/on before you run another program. - * @deprecated call disconnect, then close the underlying NXTComm - */ - @Deprecated - public void close() throws IOException { - if (!open) return; - open = false; - this.disconnect(); - nxtComm.close(); - } - - /** - * Tell the NXT that the connection is aborted. - * @throws IOException - */ - public void disconnect() throws IOException { - byte[] request = { SYSTEM_COMMAND_REPLY, NXJ_DISCONNECT }; - nxtComm.sendRequest(request, 3); // Tell NXT to disconnect - - // like boot(), this should probably mark this NXTCommand as closed - this.open = false; - } - - /** - * Put the NXT into SAMBA mode, ready to update the firmware. - * Marks this NXTCommand object as closed. - * Does never never wait for a reply from the NXT. - * - * @throws IOException - */ - public void boot() throws IOException { - if (!open) - throw new IOException("NXTCommand is closed"); - - byte[] request = {SYSTEM_COMMAND_NOREPLY, BOOT}; - request = appendString(request, "Let's dance: SAMBA"); - nxtComm.sendRequest(request, 0); - // Connection cannot be used after this command so we close it - open = false; - } - - /** - * Write data to the file - * - * @param handle the file handle - * @param data the data to write - * @return the status value - * - * @throws IOException - */ - public byte writeFile(byte handle, byte[] data, int offset, int length) throws IOException { - byte[] command = { SYSTEM_COMMAND_NOREPLY, WRITE, handle }; - int remaining = length; - int chunkStart = offset; - while (remaining > 0) { - int chunkLen = MAX_BUFFER_SIZE; - if (remaining < chunkLen) - chunkLen = remaining; - byte [] request = new byte[chunkLen + 3]; - System.arraycopy(command, 0, request, 0, command.length); - System.arraycopy(data, chunkStart, request, 3, chunkLen); - - byte status = sendSystemRequest(request, 6); - if (status != 0) - return status; - remaining -= chunkLen; - chunkStart += chunkLen; - } - return 0; - } - - /** - * Upload a file to the NXT - * - * @param file the file to upload - * @param nxtFileName the name of the file on the NXT - * @return a message saying how long it took to upload the file - * - * @throws IOException - */ - public String uploadFile(File file, String nxtFileName) throws IOException { - long millis = System.currentTimeMillis(); - FileInputStream in = new FileInputStream(file); - try - { - byte handle = openWrite(nxtFileName, (int) file.length()); - byte[] data = new byte[MAX_BUFFER_SIZE]; - int len; - while ((len = in.read(data)) > 0) - { - writeFile(handle, data, 0, len); - } - setVerify(true); - closeFile(handle); - return "Upload successful in " + (System.currentTimeMillis() - millis) + " milliseconds"; - } - finally - { - in.close(); - } - } - - /** - * Returns requested number of bytes from a file. File must first be opened - * using the openRead() command. - * - * @param handle File handle number (from openRead method) - * @param data Buffer to which data is written - * @param offset Index of first byte to be overwritten - * @param length Number of bytes to read - * @return number of bytes read - */ - public int readFile(byte handle, byte[] data, int offset, int length) throws IOException { - int remaining = length; - int chunkStart = offset; - while (remaining > 0) { - int chunkLen = MAX_BUFFER_SIZE; - if (chunkLen > remaining) - chunkLen = remaining; - byte[] request = { SYSTEM_COMMAND_REPLY, READ, handle, (byte) chunkLen, - (byte) (chunkLen >>> 8) }; - byte[] reply1 = nxtComm.sendRequest(request, chunkLen + 6); - int dataLen = (reply1[4] & 0xFF) + ((reply1[5] & 0xFF) << 8); - System.arraycopy(reply1, 6, data, chunkStart, dataLen); - chunkStart += chunkLen; - remaining -= chunkLen; - } - return length; - } - - /** - * A NXJ extension to defrag the file system - * - * @return the status byte - * @throws IOException - */ - public byte defrag() throws IOException { - byte[] request = { SYSTEM_COMMAND_NOREPLY, NXJ_DEFRAG }; - return sendSystemRequest(request, 3); - } - - /** - * Get the friendly name of the NXT - * @return the friendly name - * @throws IOException - */ - public String getFriendlyName() throws IOException { - byte[] request = { SYSTEM_COMMAND_REPLY, GET_DEVICE_INFO }; - byte[] reply = nxtComm.sendRequest(request, 33); - char nameChars[] = new char[16]; - int len = 0; - - for (int i = 0; i < 15 && reply[i + 3] != 0; i++) { - nameChars[i] = (char) reply[i + 3]; - len++; - } - - return new String(nameChars, 0, len); - } - - /** - * Set the friendly name of the NXT - * - * @param name the friendly name - * @return the status byte - * @throws IOException - */ - public byte setFriendlyName(String name) throws IOException { - byte[] request = { SYSTEM_COMMAND_NOREPLY, SET_BRICK_NAME }; - request = appendString(request, name); - - return sendSystemRequest(request, 3); - } - - /** - * Get the local address of the NXT. - * - * @return the address (used by USB and Bluetooth) - * @throws IOException - */ - public String getLocalAddress() throws IOException { - byte[] request = { SYSTEM_COMMAND_REPLY, GET_DEVICE_INFO }; - byte[] reply = nxtComm.sendRequest(request, 33); - char addrChars[] = new char[14]; - - for (int i = 0; i < 7; i++) { - addrChars[i * 2] = hexChars.charAt((reply[i + 18] >> 4) & 0xF); - addrChars[i * 2 + 1] = hexChars.charAt(reply[i + 18] & 0xF); - } - - return new String(addrChars); - } - - /** - * Get input values for a specific NXT sensor port - * - * @param port the port number - * @return the InputValues structure - * @throws IOException - */ - public InputValues getInputValues(int port) throws IOException { - byte [] request = {DIRECT_COMMAND_REPLY, GET_INPUT_VALUES, (byte)port}; - byte [] reply = nxtComm.sendRequest(request, 16); - InputValues inputValues = new InputValues(); - inputValues.inputPort = reply[3]; - // 0 is false, 1 is true. - inputValues.valid = (reply[4] != 0); - // 0 is false, 1 is true. - inputValues.isCalibrated = (reply[5] == 0); - inputValues.sensorType = reply[6]; - inputValues.sensorMode = reply[7]; - inputValues.rawADValue = (short) ((0xFF & reply[8]) | ((0xFF & reply[9]) << 8)); - inputValues.normalizedADValue = (short) ((0xFF & reply[10]) | ((0xFF & reply[11]) << 8)); - inputValues.scaledValue = (short) ((0xFF & reply[12]) | ((0xFF & reply[13]) << 8)); - inputValues.calibratedValue = (short) ((0xFF & reply[14]) | ((0xFF & reply[15]) << 8)); - - return inputValues; - } - - /** - * Retrieves the current output state for a port. - * @param port - 0 to 3 - * @return OutputState - returns a container object for output state variables. - */ - public OutputState getOutputState(int port) throws IOException { - // !! Needs to check port to verify they are correct ranges. - byte [] request = {DIRECT_COMMAND_REPLY, GET_OUTPUT_STATE, (byte)port}; - byte [] reply = nxtComm.sendRequest(request,25); - - OutputState outputState = new OutputState(port); - outputState.status = reply[2]; - outputState.outputPort = reply[3]; - outputState.powerSetpoint = reply[4]; - outputState.mode = reply[5]; - outputState.regulationMode = reply[6]; - outputState.turnRatio = reply[7]; - outputState.runState = reply[8]; - outputState.tachoLimit = (0xFF & reply[9]) | ((0xFF & reply[10]) << 8)| ((0xFF & reply[11]) << 16)| ((0xFF & reply[12]) << 24); - outputState.tachoCount = (0xFF & reply[13]) | ((0xFF & reply[14]) << 8)| ((0xFF & reply[15]) << 16)| ((0xFF & reply[16]) << 24); - outputState.blockTachoCount = (0xFF & reply[17]) | ((0xFF & reply[18]) << 8)| ((0xFF & reply[19]) << 16)| ((0xFF & reply[20]) << 24); - outputState.rotationCount = (0xFF & reply[21]) | ((0xFF & reply[22]) << 8)| ((0xFF & reply[23]) << 16)| ((0xFF & reply[24]) << 24); - return outputState; - } - - /** - * Retrieves tacho count. - * @param port - 0 to 3 - * @return tacho count - */ - public int getTachoCount(int port) throws IOException { - synchronized(this) { - byte [] request = {DIRECT_COMMAND_REPLY, GET_OUTPUT_STATE, (byte)port}; - byte [] reply = nxtComm.sendRequest(request, 25); - - int tachoCount = (0xFF & reply[13]) | ((0xFF & reply[14]) << 8)| ((0xFF & reply[15]) << 16)| ((0xFF & reply[16]) << 24); - return tachoCount; - } - } - - /** - * Tells the NXT what type of sensor you are using and the mode to operate in. - * @param port - 0 to 3 - * @param sensorType - Enumeration for sensor type (see NXTProtocol) - * @param sensorMode - Enumeration for sensor mode (see NXTProtocol) - */ - public byte setInputMode(int port, int sensorType, int sensorMode) throws IOException { - // !! Needs to check port to verify they are correct ranges. - byte [] request = {DIRECT_COMMAND_NOREPLY, SET_INPUT_MODE, (byte)port, (byte)sensorType, (byte)sensorMode}; - return sendRequest(request, 3); - } - - /** - * Returns the status for an Inter-Integrated Circuit (I2C) sensor (the - * ultrasound sensor) via the Low Speed (LS) data port. The port must first - * be configured to type LOWSPEED or LOWSPEED_9V. - * @param port 0-3 - * @return byte[0] = status, byte[1] = Bytes Ready (count of available bytes to read) - */ - public byte [] LSGetStatus(byte port) throws IOException{ - byte [] request = {DIRECT_COMMAND_REPLY, LS_GET_STATUS, port}; - byte [] reply = nxtComm.sendRequest(request,4); - byte [] returnData = {reply[2], reply[3]}; - return returnData; - } - - /** - * Reads data from an Inter-Integrated Circuit (I2C) sensor (the - * ultrasound sensor) via the Low Speed (LS) data port. The port must - * first be configured to type LOWSPEED or LOWSPEED_9V. - * Data lengths are limited to 16 bytes per command. The response will - * also contain 16 bytes, with invalid data padded with zeros. - * @param port - * @return the response - */ - public byte [] LSRead(byte port) throws IOException { - byte [] request = {DIRECT_COMMAND_REPLY, LS_READ, port}; - byte [] reply = nxtComm.sendRequest(request, 20); - - int rxLength = reply[3] & 0xFF; - if(reply[2] == 0 && rxLength >= 0) { - byte [] rxData = new byte[rxLength]; - System.arraycopy(reply, 4, rxData, 0, rxLength); - return rxData; - } - return null; - } - - /** - * Used to request data from an Inter-Integrated Circuit (I2C) sensor (the - * ultrasound sensor) via the Low Speed (LS) data port. The port must first - * be configured to type LOWSPEED or LOWSPEED_9V. - * Data lengths are limited to 16 bytes per command. - * Rx (receive) Data Length MUST be specified in the write - * command since reading from the device is done on a - * master-slave basis. - * @param txData Transmitted data. - * @param rxDataLength Receive data length. - * @param port 0-3 - * @return the status (0 = success) - */ - public byte LSWrite(byte port, byte [] txData, byte rxDataLength) throws IOException { - byte [] request = {DIRECT_COMMAND_NOREPLY, LS_WRITE, port, (byte)txData.length, rxDataLength}; - request = appendBytes(request, txData); - return sendRequest(request, 3); - } - - /** - * Read message. - * @param remoteInbox 0-9 - * @param localInbox 0-9 - * @param remove True clears the message from the remote inbox. - * @return the message as an array of bytes, excluding the trailing null-terminator or null when queue is empty - */ - public byte[] messageRead(byte remoteInbox, byte localInbox, boolean remove) throws IOException { - byte [] request = {DIRECT_COMMAND_REPLY, MESSAGE_READ, remoteInbox, localInbox, (remove ? (byte) 1 : (byte) 0)}; - byte [] reply = nxtComm.sendRequest(request, 64); - if (reply[2] == ErrorMessages.SPECIFIED_MAILBOX_QUEUE_IS_EMPTY) - return null; - this.checkStatusByte(reply); - int size = reply[4] & 0xFF; //size includes null terminator - // check whether length is in range and for null-terminator - if (size < 1 || size > 5 + reply.length || reply[4+size] != 0) - throw new LCPException("protocol error"); - byte[] message = new byte[size-1]; - System.arraycopy(reply, 5, message, 0, size-1); - return message; - } - - private void checkStatusByte(byte[] reply) throws LCPException { - byte code = reply[2]; - if (code != 0) - throw new LCPException(code); - } - - /** - * Sends a message to an inbox on the NXT for storage(?) - * For future reference, message size must be capped at 59 for USB. - * A null terminator is automatically appended and should not be included in the message. - * UNTESTED - * @param message String to send. - * @param inbox Inbox Number 0 - 9 - * @return the status (0 = success) - */ - public byte messageWrite(byte [] message, byte inbox) throws IOException { - //TODO check range of number, throw exception if message is too large - int len = message.length; - byte[] request = new byte[5 + len]; - request[0] = DIRECT_COMMAND_NOREPLY; - request[1] = MESSAGE_WRITE; - request[2] = inbox; - request[3] = (byte)(len+1); // size includes null-terminator - System.arraycopy(message, 0, request, 4, len); - request[4+len] = 0; - return sendRequest(request, 3); - } - - /** - * Plays a tone on NXT speaker. If a new tone is sent while the previous tone is playing, - * the new tone command will stop the old tone command. - * @param frequency - 100 to 2000? - * @param duration - In milliseconds. - * @return - Returns true if command worked, false if it failed. - */ - public byte playTone(int frequency, int duration) throws IOException { - byte [] request = {DIRECT_COMMAND_NOREPLY, PLAY_TONE, (byte)frequency, (byte)(frequency>>>8), (byte)duration, (byte)(duration>>>8)}; - return sendRequest(request, 3); - } - - public byte playSoundFile(String fileName, boolean repeat) throws IOException { - - byte boolVal = 0; - if(repeat) boolVal = (byte)0xFF; // Convert boolean to number - - byte [] request = {DIRECT_COMMAND_NOREPLY, PLAY_SOUND_FILE, boolVal}; - byte[] encFileName = null; - try { - encFileName = AsciizCodec.encode(fileName); - } catch (UnsupportedEncodingException e) { - System.err.println("Illegal characters in filename"); - return -1; - } - request = appendBytes(request, encFileName); - return sendRequest(request, 3); - } - - /** - * Stops sound file playing. - * @return the status (0 = success) - */ - public byte stopSoundPlayback() throws IOException { - byte [] request = {DIRECT_COMMAND_NOREPLY, STOP_SOUND_PLAYBACK}; - return sendRequest(request, 3); - } - - /** - * Resets either RotationCount or BlockTacho - * @param port Output port (0-2) - * @param relative TRUE: BlockTacho, FALSE: RotationCount - * @return the status (0 = success) - */ - public byte resetMotorPosition(int port, boolean relative) throws IOException { - // !! Needs to check port to verify they are correct ranges. - // !!! I'm not sure I'm sending boolean properly - byte boolVal = 0; - if(relative) boolVal = (byte)0xFF; - byte [] request = {DIRECT_COMMAND_NOREPLY, RESET_MOTOR_POSITION, (byte)port, boolVal}; - return sendRequest(request, 3); - } - - /** - * - * @param port - Output port (0 - 2 or 0xFF for all three) - * @param power - Setpoint for power. (-100 to 100) - * @param mode - Setting the modes MOTORON, BRAKE, and/or REGULATED. This parameter is a bitfield, so to put it in brake mode and regulated, use BRAKEMODE + REGULATED - * @param regulationMode - see NXTProtocol for enumerations - * @param turnRatio - Need two motors? (-100 to 100) - * @param runState - see NXTProtocol for enumerations - * @param tachoLimit - Number of degrees(?) to rotate before stopping. - * @return the status (0 = success) - */ - public byte setOutputState(int port, byte power, int mode, int regulationMode, int turnRatio, int runState, int tachoLimit) throws IOException { - // !! Needs to check port, power to verify they are correct ranges. - byte [] request = {DIRECT_COMMAND_NOREPLY, SET_OUTPUT_STATE, (byte)port, power, (byte)mode, (byte)regulationMode, (byte)turnRatio, (byte)runState, (byte)tachoLimit, (byte)(tachoLimit>>>8), (byte)(tachoLimit>>>16), (byte)(tachoLimit>>>24)}; - return sendRequest(request, 3); - } - - /** - * Gets device information - * - * @return a DeviceInfo structure - * @throws IOException - */ - public DeviceInfo getDeviceInfo() throws IOException { - // !! Needs to check port to verify they are correct ranges. - byte [] request = {SYSTEM_COMMAND_REPLY, GET_DEVICE_INFO}; - byte [] reply = nxtComm.sendRequest(request, 33); - DeviceInfo d = new DeviceInfo(); - d.status = reply[2]; - d.NXTname = new StringBuffer(new String(reply)).delete(18,33).delete(0, 3).toString(); - d.bluetoothAddress = Integer.toHexString(reply[18]) + ":" + Integer.toHexString(reply[19]) + ":" + Integer.toHexString(reply[20]) + ":" + Integer.toHexString(reply[21]) + ":" + Integer.toHexString(reply[22]) + ":" + Integer.toHexString(reply[23]) + ":" + Integer.toHexString(reply[24]); - d.signalStrength = (0xFF & reply[25]) | ((0xFF & reply[26]) << 8)| ((0xFF & reply[27]) << 16)| ((0xFF & reply[28]) << 24); - d.freeFlash = (0xFF & reply[29]) | ((0xFF & reply[30]) << 8)| ((0xFF & reply[31]) << 16)| ((0xFF & reply[32]) << 24); - return d; - } - - /** - * Get the fimrware version. - * leJOS NXJ returns the version of the LEGO firmware that it emulates, - * not its own version number. - * - * @return a FirmwareInfo structure. - * @throws IOException - */ - public FirmwareInfo getFirmwareVersion() throws IOException { - byte [] request = {SYSTEM_COMMAND_REPLY, GET_FIRMWARE_VERSION}; - byte [] reply = nxtComm.sendRequest(request, 7); - FirmwareInfo info = new FirmwareInfo(); - info.status = reply[2]; - if(info.status == 0) { - info.protocolVersion = reply[4] + "." + reply[3]; - info.firmwareVersion = reply[6] + "." + reply[5]; - } - return info; - } - - /** - * Deletes user flash memory. - * Not implemented by leJOS NXJ. - * @return the status (0 = success) - */ - public byte deleteUserFlash() throws IOException { - byte [] request = {SYSTEM_COMMAND_REPLY, DELETE_USER_FLASH}; - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * leJOS-specific command to set the default program - * - * @param name the default program name - * @return the status (0 is success) - * @throws IOException - */ - public byte setDefaultProgram(String name) throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_SET_DEFAULT_PROGRAM}; - byte[] encName = null; - try { - encName = AsciizCodec.encode(name); - } catch (UnsupportedEncodingException e) { - return -1; - } - request = appendBytes(request, encName); - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * leJOS-specific command to set the master volume level - * - * @param volume the master volume level - * @return the status (0 = success) - * @throws IOException - */ - public byte setVolume(byte volume) throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_SET_VOLUME, volume}; - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * leJOS-specific command to set the key click volume level - * - * @param volume the key click volume level - * @return the status (0 = success) - * @throws IOException - */ - public byte setKeyClickVolume(byte volume) throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_SET_KEY_CLICK_VOLUME, volume}; - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * leJOS-specific command to set auto-run on or off - * - * @param on true = on, false = off - * @return the status (0 = success) - * @throws IOException - */ - public byte setAutoRun(boolean on) throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_SET_AUTO_RUN, (byte) (on ? 1 : 0)}; - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * leJOS-specific command to get the master volume level - * - * @return the master volume level - * @throws IOException - */ - public int getVolume() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_VOLUME}; - byte [] reply = nxtComm.sendRequest(request, 4); - return reply[3]; - } - - /** - * leJOS-specific command to get the master volume level - * - * @return the master volume level - * @throws IOException - */ - public int getKeyClickVolume() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_KEY_CLICK_VOLUME}; - byte [] reply = nxtComm.sendRequest(request, 4); - return reply[3]; - } - - /** - * leJOS-specific command to get the auto run setring - * - * @return the auto run setting - * @throws IOException - */ - public boolean getAutoRun() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_AUTO_RUN}; - byte [] reply = nxtComm.sendRequest(request, 4); - return (reply[3] == 1); - } - - /** - * leJOS-specific command to get the NXJ firmware version - * - * @return a string with major version, minor version, and patch level and revision - * @throws IOException - */ - public String getNXJFirmwareVersion() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_VERSION}; - byte [] reply = nxtComm.sendRequest(request, 17); - int revision = (0xFF & reply[6]) | ((0xFF & reply[7]) << 8)| ((0xFF & reply[8]) << 16)| ((0xFF & reply[9]) << 24); - return reply[3] + "." + reply[4] + "." + reply[5] + "(" + revision + ")"; - } - - /** - * leJOS-specific command to get the NXJ start-up menu version - * - * @return a string with major version, minor version, patch level and revision - * @throws IOException - */ - public String getNXJMenuVersion() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_VERSION}; - byte [] reply = nxtComm.sendRequest(request, 17); - int revision = (0xFF & reply[13]) | ((0xFF & reply[14]) << 8)| ((0xFF & reply[15]) << 16)| ((0xFF & reply[16]) << 24); - return reply[10] + "." + reply[11] + "." + reply[12] + "(" + revision + ")"; - } - - /** - * leJOS-specific command to get the NXJ firmware and menu information - * - * @return a NXJFirmwareInfo object containing all the version numbers - * @throws IOException - */ - public NXJFirmwareInfo getNXJFirmwareInfo() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_VERSION}; - byte [] reply = nxtComm.sendRequest(request, 17); - NXJFirmwareInfo info = new NXJFirmwareInfo(); - info.firmwareMajorVersion = reply[3]; - info.firmwareMinorVersion = reply[4]; - info.firmwarePatchLevel = reply[5]; - info.firmwareRevision = (0xFF & reply[6]) | ((0xFF & reply[7]) << 8)| ((0xFF & reply[8]) << 16)| ((0xFF & reply[9]) << 24); - info.menuMajorVersion = reply[10]; - info.menuMinorVersion = reply[11]; - info.menuPatchLevel = reply[12]; - info.menuRevision = (0xFF & reply[13]) | ((0xFF & reply[14]) << 8)| ((0xFF & reply[15]) << 16)| ((0xFF & reply[16]) << 24); - - return info; - } - - /** - * leJOS-specific method to get the menu sleep time - * - * @return the sleep time in seconds - * @throws IOException - */ - public int getSleepTime() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_SLEEP_TIME}; - byte [] reply = nxtComm.sendRequest(request, 4); - return reply[3]; - } - - /** - * leJOS-specific command to get the default program name - * - * @return the default program name - * @throws IOException - */ - public String getDefaultProgram() throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_GET_DEFAULT_PROGRAM}; - byte [] reply = nxtComm.sendRequest(request, 23); - StringBuffer name = new StringBuffer(new String(reply)).delete(0, 3); - int lastPos = name.indexOf("\0"); - if (lastPos < 0 || lastPos > 20) lastPos = 20; - name.delete(lastPos, name.length()); - return name.toString(); - } - - /** - * leJOS-specific command to the the sleep time for the menu - * @param seconds the number of seconds before shutdown - * @return the status (0 = success) - * @throws IOException - */ - public byte setSleepTime(byte seconds) throws IOException { - byte[] request = {SYSTEM_COMMAND_REPLY, NXJ_SET_SLEEP_TIME, seconds}; - byte [] reply = nxtComm.sendRequest(request, 3); - return reply[2]; - } - - /** - * Test is connection is open - * - * @return true iff the connection is open - */ - public boolean isOpen() { - return open; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTConnection.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTConnection.java deleted file mode 100644 index b9d630c..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTConnection.java +++ /dev/null @@ -1,58 +0,0 @@ -package lejos.remote.nxt; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public abstract class NXTConnection implements StreamConnection { - - /** - * Lego Communications Protocol (LCP) I/O mode. The LCP is defined by The Lego Company to allow limited remote - * command control of a NXT brick. - * - * See the Lego Mindstorms Site. Look for the Bluetooth Developer Kit in Support | - * Files | Advanced - */ - public static final int LCP = 1; - /** - * PACKET I/O mode. This is default and is probably the best mode to use if you are talking to a - * NXT using the leJOS classes. Headers are included for each packet of data sent and received. - */ - public static final int PACKET = 0; - /** - * RAW I/O mode. This mode is just that and omits any headers. It is used normally for connections to non-NXT - * devices such as cell phones, etc. - */ - public static final int RAW = 2; - - @Override - public DataInputStream openDataInputStream() { - return new DataInputStream(openInputStream()); - } - - @Override - public InputStream openInputStream() { - return new NXTInputStream(this, 256); - } - - @Override - public abstract void close() throws IOException; - - @Override - public DataOutputStream openDataOutputStream() { - return new DataOutputStream(openOutputStream()); - } - - @Override - public OutputStream openOutputStream() { - return new NXTOutputStream(this, 256); - } - - public abstract int read(byte[] buf, int length); - - public abstract int write(byte[] buffer, int numBytes); - - public abstract int read(byte[] buf, int length, boolean b); -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTInputStream.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTInputStream.java deleted file mode 100644 index 7c88531..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTInputStream.java +++ /dev/null @@ -1,88 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Extends InputStream for BlueTooth; implements available() - * @author Roger Glassey revised on june 23, 2007, modified for Bluetooth2 - */ -public class NXTInputStream extends InputStream { - private byte buf[]; - private int bufIdx = 0, bufSize = 0; - private NXTConnection conn = null; - - NXTInputStream(NXTConnection conn, int buffSize) - { - this.conn = conn; - buf = new byte[buffSize]; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - int avail = bufSize - bufIdx; - if (avail <= 0) { - bufSize = conn.read(buf, buf.length); - if (bufSize < -1) throw new IOException(); - if (bufSize <= 0) return -1; - bufIdx = 0; - avail = bufSize; - } - - if (len > avail) - len = avail; - - System.arraycopy(buf, bufIdx, b, off, len); - bufIdx += len; - - return len; - } - - /** - * Returns one byte as an integer between 0 and 255. - * Returns -1 if the end of the stream is reached. - * Does not return till some bytes are available. - */ - @Override - public int read() throws IOException - { - if (bufIdx >= bufSize) bufSize = 0; - if (bufSize <= 0) - { - bufSize = conn.read(buf, buf.length); - if (bufSize < -1) throw new IOException(); - if (bufSize <= 0) { - System.out.println("End of file"); - return -1; - } - bufIdx = 0; - } - return buf[bufIdx++] & 0xFF; - } - - /** - * returns the number of bytes in the input buffer - can be read without blocking - */ - @Override - public int available() throws IOException - { - if (bufIdx >= bufSize) bufSize = 0; - if (bufSize == 0) { - bufIdx = 0; - bufSize = conn.read(buf, buf.length, false); - if (bufSize < -1) throw new IOException(); - if (bufSize < 0) bufSize = 0; - } - return bufSize - bufIdx; - } - - /** - * the stream is restored to its original state - ready to receive more data. - */ - @Override - public void close() - { - bufIdx = 0; - bufSize = 0; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTOutputStream.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTOutputStream.java deleted file mode 100644 index 014dae5..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTOutputStream.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Implements an OutputStream over NXT connections. - * - */ -public class NXTOutputStream extends OutputStream { - private byte[] buffer; - private int numBytes = 0; - private NXTConnection conn = null; - - NXTOutputStream(NXTConnection conn, int buffSize) - { - this.conn = conn; - buffer = new byte[buffSize]; - } - - @Override - public synchronized void write(int b) throws IOException { - if (numBytes >= buffer.length) { - flush(); - } - buffer[numBytes] = (byte) b; - numBytes++; - } - - //TODO implement write(byte[], int, int) - - @Override - public synchronized void flush() throws IOException{ - if (numBytes > 0) { - if (conn.write(buffer, numBytes) < 0) throw new IOException(); - numBytes = 0; - } - } - - @Override - public void close() throws IOException { - this.flush(); - //TODO mark stream closed - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/NXTProtocol.java b/ev3classes/src/main/java/lejos/remote/nxt/NXTProtocol.java deleted file mode 100644 index 852981b..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/NXTProtocol.java +++ /dev/null @@ -1,170 +0,0 @@ -package lejos.remote.nxt; - -/** - * LEGO Communication Protocol constants. - * - */ -public interface NXTProtocol { - // Command types constants. Indicates type of packet being sent or received. - public static final byte DIRECT_COMMAND_REPLY = 0x00; - public static final byte SYSTEM_COMMAND_REPLY = 0x01; - public static final byte REPLY_COMMAND = 0x02; - public static final byte DIRECT_COMMAND_NOREPLY = (byte)0x80; // Avoids ~100ms latency - public static final byte SYSTEM_COMMAND_NOREPLY = (byte)0x81; // Avoids ~100ms latency - - // System Commands: - public static final byte OPEN_READ = (byte)0x80; - public static final byte OPEN_WRITE = (byte)0x81; - public static final byte READ = (byte)0x82; - public static final byte WRITE = (byte)0x83; - public static final byte CLOSE = (byte)0x84; - public static final byte DELETE = (byte)0x85; - public static final byte FIND_FIRST = (byte)0x86; - public static final byte FIND_NEXT = (byte)0x87; - public static final byte GET_FIRMWARE_VERSION = (byte)0x88; - public static final byte OPEN_WRITE_LINEAR = (byte)0x89; - public static final byte OPEN_READ_LINEAR = (byte)0x8A; - public static final byte OPEN_WRITE_DATA = (byte)0x8B; - public static final byte OPEN_APPEND_DATA = (byte)0x8C; - // Many commands could be hidden between 0x8D and 0x96! - public static final byte BOOT = (byte)0x97; - public static final byte SET_BRICK_NAME = (byte)0x98; - // public static final byte MYSTERY_COMMAND = (byte)0x99; - // public static final byte MYSTERY_COMMAND = (byte)0x9A; - public static final byte GET_DEVICE_INFO = (byte)0x9B; - // commands could be hidden here... - public static final byte DELETE_USER_FLASH = (byte)0xA0; - public static final byte POLL_LENGTH = (byte)0xA1; - public static final byte POLL = (byte)0xA2; - - // Poll constants: - public static final byte POLL_BUFFER = (byte)0x00; - public static final byte HIGH_SPEED_BUFFER = (byte)0x01; - - // Direct Commands - public static final byte START_PROGRAM = 0x00; - public static final byte STOP_PROGRAM = 0x01; - public static final byte PLAY_SOUND_FILE = 0x02; - public static final byte PLAY_TONE = 0x03; - public static final byte SET_OUTPUT_STATE = 0x04; - public static final byte SET_INPUT_MODE = 0x05; - public static final byte GET_OUTPUT_STATE = 0x06; - public static final byte GET_INPUT_VALUES = 0x07; - public static final byte RESET_SCALED_INPUT_VALUE = 0x08; - public static final byte MESSAGE_WRITE = 0x09; - public static final byte RESET_MOTOR_POSITION = 0x0A; - public static final byte GET_BATTERY_LEVEL = 0x0B; - public static final byte STOP_SOUND_PLAYBACK = 0x0C; - public static final byte KEEP_ALIVE = 0x0D; - public static final byte LS_GET_STATUS = 0x0E; - public static final byte LS_WRITE = 0x0F; - public static final byte LS_READ = 0x10; - public static final byte GET_CURRENT_PROGRAM_NAME = 0x11; - // public static final byte MYSTERY_OPCODE = 0x12; // ???? - public static final byte MESSAGE_READ = 0x13; - // public static final byte POSSIBLY_MORE_HIDDEN = 0x14; // ???? - - // NXJ additions - // TODO NXJ commands should be direct commands. - // At the moment, the NXJ commands are system commands. However, the LEGO firmware - // does not respond with an error code to unknown system commands. Instead, it seems to - // return the reply of the last successful command or something similar. - // Hence, the NXJ opcodes should be declared as direct commands. The LEGO firmware will - // reply with error 0xBE (Unknown command opcode) for all direct command - // opcodes from 0x22 to 0xff (tested with Firmware 1.31). I suggest the usage of - // opcodes >= 0x80. - public static final byte NXJ_DISCONNECT = 0x20; - public static final byte NXJ_DEFRAG = 0x21; - public static final byte NXJ_SET_DEFAULT_PROGRAM = 0x22; - public static final byte NXJ_SET_SLEEP_TIME = 0x23; - public static final byte NXJ_SET_VOLUME = 0x24; - public static final byte NXJ_SET_KEY_CLICK_VOLUME = 0x25; - public static final byte NXJ_SET_AUTO_RUN = 0x26; - public static final byte NXJ_GET_VERSION = 0x27; - public static final byte NXJ_GET_DEFAULT_PROGRAM = 0x28; - public static final byte NXJ_GET_SLEEP_TIME = 0x29; - public static final byte NXJ_GET_VOLUME = 0x2A; - public static final byte NXJ_GET_KEY_CLICK_VOLUME = 0x2B; - public static final byte NXJ_GET_AUTO_RUN = 0x2C; - public static final byte NXJ_PACKET_MODE = (byte)0xff; - - // Output state constants - // "Mode": - /** Turn on the specified motor */ - public static final byte MOTORON = 0x01; - /** Use run/brake instead of run/float in PWM */ - public static final byte BRAKE = 0x02; - /** Turns on the regulation */ - public static final byte REGULATED = 0x04; - - // "Regulation Mode": - /** No regulation will be enabled */ - public static final byte REGULATION_MODE_IDLE = 0x00; - /** Power control will be enabled on specified output */ - public static final byte REGULATION_MODE_MOTOR_SPEED = 0x01; - /** Synchronization will be enabled (Needs enabled on two output) */ - public static final byte REGULATION_MODE_MOTOR_SYNC = 0x02; - - // "RunState": - /** Output will be idle */ - public static final byte MOTOR_RUN_STATE_IDLE = 0x00; - /** Output will ramp-up */ - public static final byte MOTOR_RUN_STATE_RAMPUP = 0x10; - /** Output will be running */ - public static final byte MOTOR_RUN_STATE_RUNNING = 0x20; - /** Output will ramp-down */ - public static final byte MOTOR_RUN_STATE_RAMPDOWN = 0x40; - - // Input Mode Constants - // "Port Type": - /** */ - public static final byte NO_SENSOR = 0x00; - /** */ - public static final byte SWITCH = 0x01; - /** */ - public static final byte TEMPERATURE = 0x02; - /** */ - public static final byte REFLECTION = 0x03; - /** */ - public static final byte ANGLE = 0x04; - /** */ - public static final byte LIGHT_ACTIVE = 0x05; - /** */ - public static final byte LIGHT_INACTIVE = 0x06; - /** */ - public static final byte SOUND_DB = 0x07; - /** */ - public static final byte SOUND_DBA = 0x08; - /** */ - public static final byte CUSTOM = 0x09; - /** */ - public static final byte LOWSPEED = 0x0A; - /** */ - public static final byte LOWSPEED_9V = 0x0B; - /** */ - public static final byte NO_OF_SENSOR_TYPES = 0x0C; - - // "Port Mode": - /** */ - public static final byte RAWMODE = 0x00; - /** */ - public static final byte BOOLEANMODE = 0x20; - /** */ - public static final byte TRANSITIONCNTMODE = 0x40; - /** */ - public static final byte PERIODCOUNTERMODE = 0x60; - /** */ - public static final byte PCTFULLSCALEMODE = (byte)0x80; - /** */ - public static final byte CELSIUSMODE = (byte)0xA0; - /** */ - public static final byte FAHRENHEITMODE = (byte)0xC0; - /** */ - public static final byte ANGLESTEPSMODE = (byte)0xE0; - /** */ - public static final byte SLOPEMASK = 0x1F; - /** */ - public static final byte MODEMASK = (byte)0xE0; -} - - diff --git a/ev3classes/src/main/java/lejos/remote/nxt/OutputConnection.java b/ev3classes/src/main/java/lejos/remote/nxt/OutputConnection.java deleted file mode 100644 index 8ab765f..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/OutputConnection.java +++ /dev/null @@ -1,18 +0,0 @@ -package lejos.remote.nxt; - -import java.io.*; - -public interface OutputConnection extends Connection { - /** - * Open and return a data output stream for a connection. - * @return the data output stream - */ - public DataOutputStream openDataOutputStream(); - - /** - * Open and return an output stream for a connection. - * @return the output stream - */ - public OutputStream openOutputStream(); - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/OutputState.java b/ev3classes/src/main/java/lejos/remote/nxt/OutputState.java deleted file mode 100644 index 79f54c7..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/OutputState.java +++ /dev/null @@ -1,27 +0,0 @@ -package lejos.remote.nxt; - -/** - * Container for holding the output state values. - * - * @author Brian Bagnall - * @version 0.2 September 9, 2006 - * @see NXTCommand - * - */ -public class OutputState { - public byte status; // Status of the NXTCommand.getOutputState command. - public int outputPort; // (Range: 0 to 2) - public byte powerSetpoint; // -100 to 100 - public int mode; //(bit-field) // see NXTProtocol for enumeration - public int regulationMode; // see NXTProtocol for enumeration - public byte turnRatio; // -100 to 100 - public int runState; // see NXTProtocol for enumeration - public long tachoLimit; // Current limit on a movement in progress, if any - public int tachoCount; // Internal count. Number of counts since last reset of the motor counter) - public int blockTachoCount; // Current position relative to last programmed movement - public int rotationCount; // Current position relative to last reset of the rotation sensor for this motor) - - public OutputState(int port) { - outputPort = port; - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXT.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXT.java deleted file mode 100644 index 19faf15..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXT.java +++ /dev/null @@ -1,163 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; -import java.util.ArrayList; - -import lejos.hardware.Audio; -import lejos.hardware.BrickFinder; -import lejos.hardware.Key; -import lejos.hardware.Keys; -import lejos.hardware.LED; -import lejos.hardware.Power; -import lejos.hardware.LocalBTDevice; -import lejos.hardware.LocalWifiDevice; -import lejos.hardware.lcd.Font; -import lejos.hardware.lcd.GraphicsLCD; -import lejos.hardware.lcd.TextLCD; -import lejos.hardware.port.Port; -import lejos.hardware.port.PortException; -import lejos.hardware.video.Video; - -public class RemoteNXT implements NXT { - - private NXTCommand nxtCommand; - private NXTComm nxtComm; - private Power battery; - private String name; - private Audio audio; - - protected ArrayList ports = new ArrayList(); - - private void createPorts() - { - // Create the port objects - ports.add(new RemoteNXTPort("S1", RemoteNXTPort.SENSOR_PORT, 0, nxtCommand)); - ports.add(new RemoteNXTPort("S2", RemoteNXTPort.SENSOR_PORT, 1, nxtCommand)); - ports.add(new RemoteNXTPort("S3", RemoteNXTPort.SENSOR_PORT, 2, nxtCommand)); - ports.add(new RemoteNXTPort("S4", RemoteNXTPort.SENSOR_PORT, 3, nxtCommand)); - ports.add(new RemoteNXTPort("A", RemoteNXTPort.MOTOR_PORT, 0, nxtCommand)); - ports.add(new RemoteNXTPort("B", RemoteNXTPort.MOTOR_PORT, 1, nxtCommand)); - ports.add(new RemoteNXTPort("C", RemoteNXTPort.MOTOR_PORT, 2, nxtCommand)); - } - - public RemoteNXT(String name, NXTCommConnector connector) throws IOException { - this.name = name; - connect(connector); - createPorts(); - } - - public RemoteNXT(String name, byte[] address) { - createPorts(); - this.name = name; - } - - public void connect(NXTCommConnector connector) throws IOException { - nxtComm = new NXTComm(connector); - System.out.println("Connecting to " + name); - boolean open = nxtComm.open(name, NXTConnection.LCP); - if (!open) throw new IOException("Failed to connect to " + name); - System.out.println("Connected");; - nxtCommand = new NXTCommand(nxtComm); - System.out.println("Creating remote battery"); - battery = new RemoteNXTBattery(nxtCommand); - audio = new RemoteNXTAudio(nxtCommand); - } - - public static NXT get(String name, NXTCommConnector connector) throws IOException { - return new RemoteNXT(name, connector); - } - - @Override - public Port getPort(String portName) { - for(RemoteNXTPort p : ports) - if (p.getName().equals(portName)) - return p; - throw new IllegalArgumentException("No such port " + portName); - } - - @Override - public Power getPower() { - return battery; - } - - @Override - public Audio getAudio() { - return audio; - } - - @Override - public Video getVideo() { - return null; - } - - @Override - public TextLCD getTextLCD() { - throw new UnsupportedOperationException("Remote LCD not supported on the NXT"); - } - - @Override - public TextLCD getTextLCD(Font f) { - throw new UnsupportedOperationException("Remote LCD not supported on the NXT"); - } - - @Override - public GraphicsLCD getGraphicsLCD() { - throw new UnsupportedOperationException("Remote LCD not supported on the NXT"); - } - - @Override - public boolean isLocal() { - return false; - } - - @Override - public String getType() { - return "NXT"; - } - - @Override - public String getName() { - try { - return nxtCommand.getFriendlyName(); - } catch (IOException e) { - throw new PortException(e); - } - } - - @Override - public LocalBTDevice getBluetoothDevice() { - throw new UnsupportedOperationException("localBluetoothDevice not supported on the NXT"); - } - - @Override - public LocalWifiDevice getWifiDevice() { - throw new UnsupportedOperationException("localWifiDevice not supported on the NXT"); - } - - @Override - public void setDefault() { - BrickFinder.setDefault(this); - } - - @Override - public Key getKey(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public LED getLED() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Keys getKeys() { - // TODO Auto-generated method stub - return null; - } - - public NXTCommand getNXTCommand() { - return nxtCommand; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAnalogPort.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAnalogPort.java deleted file mode 100644 index 1f10dbf..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAnalogPort.java +++ /dev/null @@ -1,121 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.PortException; -import lejos.hardware.sensor.EV3SensorConstants; -import lejos.hardware.sensor.SensorConstants; - -/** - * This class provides access to the EV3 Analog based sensor ports and other - * analog data sources. - * - * @author Lawrie Griffiths - * - */ -public class RemoteNXTAnalogPort extends RemoteNXTIOPort implements AnalogPort -{ - //TODO: If we ever implement reading of pin 6 on the NXT or return color sensor data - // we must ensure that the correct reference value is used. This should be 3.3V - // Note that even with this the readings for the color sensor may be slightly off - // due to the supply voltage on the NXT being 4.5V v the EV3 5.0V. We may want - // to correct for this. - public RemoteNXTAnalogPort(NXTCommand nxtCommand) { - super(nxtCommand); - } - - private int id; - private int type, mode; - - // The following method provide compatibility with NXT sensors - - /** - * Set the sensor type and mode - * @param type the sensor type - * @param mode the sensor mode - * @return true if success - */ - public boolean setTypeAndMode(int type, int mode) { - this.type = type; - this.mode = mode; - try { - nxtCommand.setInputMode(id, type, mode); - } catch (IOException e) { - throw new PortException(e); - } - return true; - } - - /** - * Set the sensor type - * @param type the sensor type - * @return true if success - */ - public boolean setType(int type) { - this.type = type; - setTypeAndMode(type, mode); - return true; - } - - /** - * Set the sensor mode - * @param mode the sensor mode - * @return true if success - */ - public boolean setMode(int mode) { - this.mode = mode; - setTypeAndMode(type, mode); - return true; - } - - - /** - * get the type of the port - * @param port - * @return true if sucesss - */ - public static int getPortType(int port) - { - if (port > PORTS || port < 0) - return CONN_ERROR; - return 0; - } - - private int readRawValue() - { - try { - InputValues vals = nxtCommand.getInputValues(id); - return vals.rawADValue; - } catch (IOException e) { - throw new PortException(e); - } - } - - /** - * Get the type of analog sensor (if any) attached to the port - * @param port - * @return the type of analog sensor - */ - public static int getAnalogSensorType(int port) - { - if (port > PORTS || port < 0) - return CONN_ERROR; - return 0; - } - - @Override - public void getFloats(float[] vals, int offset, int length) { - throw new UnsupportedOperationException("Not supported for a remote NXT"); - } - - @Override - public float getPin6() { - throw new UnsupportedOperationException("Not supported for a remote NXT"); - } - - @Override - public float getPin1() { - return (float)readRawValue()*EV3SensorConstants.ADC_REF/SensorConstants.NXT_ADC_RES; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAudio.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAudio.java deleted file mode 100644 index b2d14e9..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTAudio.java +++ /dev/null @@ -1,116 +0,0 @@ -package lejos.remote.nxt; - -import java.io.File; -import java.io.IOException; - -import lejos.hardware.Audio; -import lejos.hardware.port.PortException; -import lejos.utility.Delay; - -public class RemoteNXTAudio implements Audio { - private NXTCommand nxtCommand; - - public static int C2 = 523; - - public RemoteNXTAudio(NXTCommand nxtCommand) { - this.nxtCommand = nxtCommand; - } - - @Override - public void systemSound(int aCode) - { - if (aCode == 0) - playTone(600, 200); - else if (aCode == 1) - { - playTone(600, 150); - pause(200); - playTone(600, 150); - pause(150); - } - else if (aCode == 2)// C major arpeggio - for (int i = 4; i < 8; i++) - { - playTone(C2 * i / 4, 100); - pause(100); - } - else if (aCode == 3) - for (int i = 7; i > 3; i--) - { - playTone(C2 * i / 4, 100); - pause(100); - } - else if (aCode == 4) - { - playTone(100, 500); - pause(500); - } - } - - private void pause(int duration) { - Delay.msDelay(duration); - } - - @Override - public void playTone(int frequency, int duration, int aVolume) { - try { - nxtCommand.playTone(frequency, duration); - } catch (IOException ioe) { - throw new PortException(ioe); - } - } - - @Override - public void playTone(int frequency, int duration) { - try { - nxtCommand.playTone(frequency, duration); - } catch (IOException ioe) { - throw new PortException(ioe); - } - } - - @Override - public int playSample(File file, int vol) { - try { - return nxtCommand.playSoundFile(file.getName(), false); - } catch (IOException ioe) { - throw new PortException(ioe); - } - } - - @Override - public int playSample(File file) { - try { - return nxtCommand.playSoundFile(file.getName(), false); - } catch (IOException ioe) { - throw new PortException(ioe); - } - } - - @Override - public int playSample(byte[] data, int offset, int len, int freq, int vol) { - throw new UnsupportedOperationException("playSample with data not supported on NXT"); - } - - @Override - public void playNote(int[] inst, int freq, int len) { - throw new UnsupportedOperationException("playNote not supported on NXT"); - - } - - @Override - public void setVolume(int vol) { - throw new UnsupportedOperationException("setVolume not supported on NXT"); - - } - - @Override - public int getVolume() { - throw new UnsupportedOperationException("getVolume not supported on NXT"); - } - - @Override - public void loadSettings() { - // Do nothing - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTBattery.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTBattery.java deleted file mode 100644 index 96f3d25..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTBattery.java +++ /dev/null @@ -1,52 +0,0 @@ -package lejos.remote.nxt; - -import java.io.*; - -import lejos.hardware.Power; -import lejos.hardware.port.PortException; - -/** - * Battery readings from a remote NXT. - */ -public class RemoteNXTBattery implements Power, NXTProtocol { - - private NXTCommand nxtCommand; - - public RemoteNXTBattery(NXTCommand nxtCommand) { - this.nxtCommand = nxtCommand; - } - - /** - * The NXT uses 6 batteries of 1500 mV each. - * @return Battery voltage in mV. ~9000 = full. - */ - public int getVoltageMilliVolt() { - /* - * calculation from LEGO firmware - */ - try { - return nxtCommand.getBatteryLevel(); - } catch (IOException e) { - throw new PortException(e); - } - } - - /** - * The NXT uses 6 batteries of 1.5 V each. - * @return Battery voltage in Volt. ~9V = full. - */ - public float getVoltage() { - return (float)(getVoltageMilliVolt() * 0.001); - } - - @Override - public float getBatteryCurrent() { - throw new UnsupportedOperationException("Battery current not supported by the NXT"); - } - - @Override - public float getMotorCurrent() { - throw new UnsupportedOperationException("Motor current not supported by the NXT"); - } -} - diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTI2CPort.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTI2CPort.java deleted file mode 100644 index 0556415..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTI2CPort.java +++ /dev/null @@ -1,149 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -import lejos.hardware.port.I2CException; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.PortException; - -public class RemoteNXTI2CPort extends RemoteNXTIOPort implements I2CPort -{ - private int type; - private int mode; - private int id; - - public RemoteNXTI2CPort(NXTCommand nxtCommand) { - super(nxtCommand); - } - - protected boolean getChanged() - { - return false; - } - - protected byte getStatus() - { - return 0; - } - - protected void reset() - { - // Do nothing - } - - protected void setOperatingMode(int typ, int mode) - { - // Do nothing - } - - protected boolean initSensor() - { - return true; - } - - /** - * allow access to the specified port - * @param p port number to open - */ - public boolean open(int t, int p, RemoteNXTPort r) - { - if (!super.open(t, p, r)) - return false; - if (!initSensor()) - { - super.close(); - return false; - } - return true; - } - - /** - * High level i2c interface. Perform a complete i2c transaction and return - * the results. Writes the specified data to the device and then reads the - * requested bytes from it. - * @param deviceAddress The I2C device address. - * @param writeBuf The buffer containing data to be written to the device. - * @param writeOffset The offset of the data within the write buffer - * @param writeLen The number of bytes to write. - * @param readBuf The buffer to use for the transaction results - * @param readOffset Location to write the results to - * @param readLen The length of the read - */ - public synchronized void i2cTransaction(int deviceAddress, byte[]writeBuf, - int writeOffset, int writeLen, byte[] readBuf, int readOffset, - int readLen) - { - System.out.println("Remote I2C transaction on port: " + port + " , address: " + deviceAddress); - byte [] txData = new byte[writeLen + 1]; - txData[0] =(byte) deviceAddress; - System.arraycopy(writeBuf, writeOffset, txData, 1, writeLen); - int status; - try { - nxtCommand.LSWrite((byte) port, txData, (byte) readLen); - } catch (IOException e) { - throw new PortException(e); - } - - do { - try { - byte[] ret = nxtCommand.LSGetStatus((byte) port); - if (ret == null || ret.length < 1) throw new I2CException("Remote NXT I2C LSGetStatus error"); - status = (int) ret[0]; - } catch (IOException e) { - throw new PortException(e); - } - - } while (status == ErrorMessages.PENDING_COMMUNICATION_TRANSACTION_IN_PROGRESS || - status == ErrorMessages.SPECIFIED_CHANNEL_CONNECTION_NOT_CONFIGURED_OR_BUSY); - - try { - byte [] ret = nxtCommand.LSRead((byte) port); - if (ret == null) throw new I2CException("Remote NXT I2C LSRead error"); - if (readLen != ret.length) throw new I2CException("Remote NXT I2C wrong number of bytes read"); - if (readLen > 0) - System.arraycopy(ret, 0, readBuf, readOffset, readLen); - } catch (IOException e) { - throw new PortException(e); - } - } - - /** - * Set the sensor type and mode - * @param type the sensor type - * @param mode the sensor mode - * @return true if success - */ - public boolean setTypeAndMode(int type, int mode) { - this.type = type; - this.mode = mode; - try { - nxtCommand.setInputMode(id, type, mode); - } catch (IOException e) { - throw new PortException(e); - } - return true; - } - - /** - * Set the sensor type - * @param type the sensor type - * @return true if success - */ - public boolean setType(int type) { - this.type = type; - setTypeAndMode(type, mode); - return true; - } - - /** - * Set the sensor mode - * @param mode the sensor mode - * @return true if success - */ - public boolean setMode(int mode) { - this.mode = mode; - setTypeAndMode(type, mode); - return true; - } - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTIOPort.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTIOPort.java deleted file mode 100644 index 20116d0..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTIOPort.java +++ /dev/null @@ -1,126 +0,0 @@ -package lejos.remote.nxt; - -import lejos.hardware.port.BasicSensorPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.sensor.EV3SensorConstants; - -/** - * This class provides the base operations for remote NXT sensor ports. - * - * @author Lawrie Griffiths - * - */ -public abstract class RemoteNXTIOPort implements IOPort, BasicSensorPort, EV3SensorConstants -{ - protected int port = -1; - protected int typ = -1; - protected RemoteNXTPort ref; - protected static byte [] dc = new byte[3*PORTS]; - protected int currentMode = 0; - protected static RemoteNXTIOPort [][] openPorts = new RemoteNXTIOPort[RemoteNXTPort.MOTOR_PORT+1][PORTS]; - protected NXTCommand nxtCommand; - - public RemoteNXTIOPort(NXTCommand nxtCommand) { - this.nxtCommand = nxtCommand; - } - - /** {@inheritDoc} - */ - @Override - public String getName() - { - return ref.getName(); - } - - /** {@inheritDoc} - */ - @Override - public int getMode() - { - return currentMode; - } - - /** {@inheritDoc} - */ - @Override - public int getType() - { - return 0; - } - - /** {@inheritDoc} - */ - @Override - public boolean setMode(int mode) - { - currentMode = mode; - return true; - } - - /** {@inheritDoc} - */ - @Override - public boolean setType(int type) - { - throw new UnsupportedOperationException("This operation is for legacy modes only"); - } - - /** {@inheritDoc} - */ - @Override - public boolean setTypeAndMode(int type, int mode) - { - setType(type); - setMode(mode); - return true; - } - - /** - * Open the sensor port. Ensure that the port is only opened once. - * @param typ The type of port motor/sensor - * @param port the port number - * @param ref the Port ref for this port - * @return true if success - */ - public boolean open(int typ, int port, RemoteNXTPort ref) - { - synchronized (openPorts) - { - if (openPorts[typ][port] == null) - { - openPorts[typ][port] = this; - this.port = port; - this.typ = typ; - this.ref = ref; - return true; - } - return false; - } - } - - /** {@inheritDoc} - */ - @Override - public void close() - { - if (port == -1) - throw new IllegalStateException("Port is not open"); - synchronized (openPorts) - { - openPorts[typ][port] = null; - port = -1; - } - } - - - /** - * Set the port pins up ready for use. - * @param mode The EV3 pin mode - */ - public boolean setPinMode(int mode) - { - // Nothing required on the NXT - return false; - } - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTMotorPort.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTMotorPort.java deleted file mode 100644 index 776180c..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTMotorPort.java +++ /dev/null @@ -1,96 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; - -import lejos.hardware.motor.MotorRegulator; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.PortException; -import lejos.hardware.port.TachoMotorPort; - -/** - * - * Abstraction for an EV3 output port. - * - * TODO: Sort out a better way to do this, or least clean up the magic numbers. - * - */ -public class RemoteNXTMotorPort extends RemoteNXTIOPort implements NXTProtocol, TachoMotorPort { - public RemoteNXTMotorPort(NXTCommand nxtCommand) { - super(nxtCommand); - } - - /** - * Low-level method to control a motor. - * - * @param power power from 0-100 - * @param mode defined in BasicMotorPort. 1=forward, 2=backward, 3=stop, 4=float. - * @see BasicMotorPort#FORWARD - * @see BasicMotorPort#BACKWARD - * @see BasicMotorPort#FLOAT - * @see BasicMotorPort#STOP - */ - public void controlMotor(int power, int mode) - { - int lcpMode = 0, lcpPower = power, runState = 0; - - if (mode == 1) { // forward - lcpMode = MOTORON; - runState = MOTOR_RUN_STATE_RUNNING; - } else if (mode == 2) { // backward - lcpMode = MOTORON; - lcpPower = -lcpPower; - runState = MOTOR_RUN_STATE_RUNNING; - } else if (mode == 3) { // stop - lcpPower = 0; - lcpMode = BRAKE; - runState = MOTOR_RUN_STATE_IDLE; - } else { // float - lcpPower = 0; - lcpMode = 0; - runState = MOTOR_RUN_STATE_IDLE; - } - try { - nxtCommand.setOutputState((byte) port, (byte) lcpPower, lcpMode, REGULATION_MODE_IDLE, 0, runState, 0); - } catch (IOException e) { - throw new PortException(e); - } - } - - - /** - * returns tachometer count - */ - public int getTachoCount() - { - try { - return nxtCommand.getTachoCount(port); - } catch (IOException e) { - throw new PortException(e); - } - } - - /** - *resets the tachometer count to 0; - */ - public void resetTachoCount() - { - try { - nxtCommand.resetMotorPosition(port, false); - } catch (IOException e) { - throw new PortException(e); - } - } - - public void setPWMMode(int mode) - { - // TODO: How can we support this on a remote NXT? - } - - @Override - public MotorRegulator getRegulator() - { - // TODO Does it make sense to allow this to be remote? - throw(new UnsupportedOperationException("Remote regulators are not supported")); - //return null; - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTPort.java b/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTPort.java deleted file mode 100644 index 0a54057..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/RemoteNXTPort.java +++ /dev/null @@ -1,71 +0,0 @@ -package lejos.remote.nxt; - -import lejos.hardware.DeviceException; -import lejos.hardware.port.AnalogPort; -import lejos.hardware.port.BasicMotorPort; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.IOPort; -import lejos.hardware.port.Port; -import lejos.hardware.port.TachoMotorPort; -import lejos.hardware.sensor.EV3SensorConstants; - -public class RemoteNXTPort implements Port -{ - public static final int SENSOR_PORT = 0; - public static final int MOTOR_PORT = 1; - protected String name; - protected int typ; - protected int portNum; - protected NXTCommand nxtCommand; - - public RemoteNXTPort(String name, int typ, int portNum, NXTCommand nxtCommand ) - { - if (typ < SENSOR_PORT || typ > MOTOR_PORT) - throw new IllegalArgumentException("Invalid port type"); - if (portNum < 0 || - (typ == SENSOR_PORT && portNum >= EV3SensorConstants.PORTS) || - (typ == MOTOR_PORT && portNum >= EV3SensorConstants.MOTORS)) - throw new IllegalArgumentException("Invalid port number"); - this.name = name; - this.typ = typ; - this.portNum = portNum; - this.nxtCommand = nxtCommand; - } - - /** {@inheritDoc} - */ - @Override - public String getName() - { - return name; - } - - /** {@inheritDoc} - */ - @Override - public T open(Class portclass) - { - RemoteNXTIOPort p = null; - switch(typ) - { - case SENSOR_PORT: - if (portclass == RemoteNXTAnalogPort.class || portclass == AnalogPort.class) - p = new RemoteNXTAnalogPort(nxtCommand); - else if (portclass == RemoteNXTI2CPort.class|| portclass == I2CPort.class) - p = new RemoteNXTI2CPort(nxtCommand); - break; - case MOTOR_PORT: - if (portclass == BasicMotorPort.class) - p = new RemoteNXTMotorPort(nxtCommand); - else if (portclass == TachoMotorPort.class) - p = new RemoteNXTMotorPort(nxtCommand); - // TODO: Should we also allow Encoder? - break; - } - if (p == null) - throw new IllegalArgumentException("Invalid port interface"); - if (!p.open(typ, portNum, this)) - throw new DeviceException("unable to open port"); - return portclass.cast(p); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/SocketConnection.java b/ev3classes/src/main/java/lejos/remote/nxt/SocketConnection.java deleted file mode 100644 index ae68cff..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/SocketConnection.java +++ /dev/null @@ -1,51 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; - -public class SocketConnection extends NXTConnection { - private Socket socket; - private InputStream is; - private OutputStream os; - - public SocketConnection(Socket socket) { - this.socket = socket; - try { - is = socket.getInputStream(); - os = socket.getOutputStream(); - } catch (IOException e) { - // Ignore for the moment - } - } - - @Override - public void close() throws IOException { - socket.close(); - } - - @Override - public int read(byte[] buf, int length) { - try { - return is.read(buf, 0, length); - } catch (IOException e) { - return -2; - } - } - - @Override - public int write(byte[] buffer, int numBytes) { - try { - os.write(buffer, 0, numBytes); - return 0; - } catch (IOException e) { - return -2; - } - } - - @Override - public int read(byte[] buf, int length, boolean b) { - return read(buf,length); - } -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/SocketConnector.java b/ev3classes/src/main/java/lejos/remote/nxt/SocketConnector.java deleted file mode 100644 index 2f0b576..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/SocketConnector.java +++ /dev/null @@ -1,36 +0,0 @@ -package lejos.remote.nxt; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -public class SocketConnector extends NXTCommConnector { - - @Override - public NXTConnection connect(String target, int mode) { - try { - return new SocketConnection(new Socket(target,8888)); - } catch (IOException e) { - System.err.println("Exception connecting to " + target + ": " + e); - return null; - } - } - - @Override - public NXTConnection waitForConnection(int timeout, int mode) { - try { - ServerSocket ss = new ServerSocket(8888); - return new SocketConnection(ss.accept()); - } catch (IOException e) { - System.err.println("Exception waiting for connection: " + e); - return null; - } - } - - @Override - public boolean cancel() { - // TODO Auto-generated method stub - return false; - } - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/StreamConnection.java b/ev3classes/src/main/java/lejos/remote/nxt/StreamConnection.java deleted file mode 100644 index 2102174..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/StreamConnection.java +++ /dev/null @@ -1,18 +0,0 @@ -package lejos.remote.nxt; - -/** - * - * This interface defines the capabilities that a stream connection must have. - * - * StreamConnections have one underlying InputStream and one OutputStream. - * - * Opening a DataInputStream counts as opening an InputStream and opening a DataOutputStream counts as opening an OutputStream. - * - * Trying to open another InputStream or OutputStream causes an IOException. - * - * Trying to open the InputStream or OutputStream after they have been closed causes an IOException - * - */ -public interface StreamConnection extends InputConnection, OutputConnection { - -} diff --git a/ev3classes/src/main/java/lejos/remote/nxt/package-info.java b/ev3classes/src/main/java/lejos/remote/nxt/package-info.java deleted file mode 100644 index 2d4b855..0000000 --- a/ev3classes/src/main/java/lejos/remote/nxt/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Remote NXT access over Bluetooth - */ -package lejos.remote.nxt; diff --git a/ev3classes/src/main/java/lejos/remote/rcx/LLC.java b/ev3classes/src/main/java/lejos/remote/rcx/LLC.java deleted file mode 100644 index 489562c..0000000 --- a/ev3classes/src/main/java/lejos/remote/rcx/LLC.java +++ /dev/null @@ -1,141 +0,0 @@ -package lejos.remote.rcx; - -import lejos.hardware.device.RCXLink; -import lejos.hardware.port.I2CPort; -import lejos.hardware.port.Port; - -/** - * Emulates RCX LLC class using the RCXLink class. - * - **/ -public class LLC { - private static RCXLink link; - private static byte[] data = new byte[1]; - - private LLC() { - } - - /** - * Initialize LLC and set port - **/ - public static void init(I2CPort port){ - link = new RCXLink(port); - link.setDefaultSpeed(); - link.flush(); - } - - /** - * Initialize LLC and set port - **/ - public static void init(Port port){ - link = new RCXLink(port); - link.setDefaultSpeed(); - link.flush(); - } - - /** - * Initialize LLC an - **/ - public static void init() { - link.setDefaultSpeed(); - link.flush(); - } - - /** - * Set sensor port - **/ - public static void setPort(I2CPort port) { - link = new RCXLink(port); - } - - /** - * read a single byte, if available - * @return the byte read, or -1 if no byte is available - **/ - public static int read() { - int numBytes = link.bytesAvailable(); - if (numBytes == 0) return -1; - data[0] = 0; - link.readBytes(data); - return (data[0] & 0xFF); - } - - /** - * Write raw bytes - * - * @param buf the bytes to write - * @param len the number of bytes - */ - private static void write(byte [] buf, int len) { - link.sendBytes(buf, len); - } - - /** - * Indicate whether the last send is still active - * @return true if still sending, else false - **/ - public static boolean isSending() { - return false; - } - - /** - * Return the error status of the last send - * @return true if still sending, else false - **/ - public static boolean isSendError() { - return false; - } - - /** - * Send a number of bytes and wait for completion of transmission - * @param buf the array of bytes to send - * @param len the number of bytes to send - * @return true if the send is successful, else false - **/ - public static boolean sendBytes(byte [] buf, int len) { - LLC.write(buf, len); - return true; - } - - /** - * wait a little while for a byte to become available - * @return the byte received, or -1 if no byte available - **/ - public static int receive() { - int r; - for(int i=0;i<10;i++) { - r = LLC.read(); - if (r >= 0) return r; - Thread.yield(); - } - return -1; - } - - /** - * Sets long range transmision. - */ - public static void setRangeLong() - { - link.setRangeLong(); - } - - /** - * Sets short range transmision. - */ - public static void setRangeShort() - { - link.setRangeLong(); - } - - /** - * Return the RCXLink object associated with LLC - * - * @return the RCXLink used - */ - public static RCXLink getLink() { - return link; - } -} - - - diff --git a/ev3classes/src/main/java/lejos/remote/rcx/LLCHandler.java b/ev3classes/src/main/java/lejos/remote/rcx/LLCHandler.java deleted file mode 100644 index 37109ac..0000000 --- a/ev3classes/src/main/java/lejos/remote/rcx/LLCHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -package lejos.remote.rcx; - -import lejos.hardware.port.I2CPort; -import lejos.utility.Delay; - -/** - * Packet handler than implement the LLC packet protocol. - * Deals with packets and acks. - * Supports independent streams of data in both directions. - * - **/ -public class LLCHandler extends PacketHandler { - - private byte op; - private boolean gotAck = false; - private boolean gotPacket = false; - private byte [] inPacket = new byte [3]; - private byte [] ackPacket = new byte [2]; - private int inPacketLength; - - public LLCHandler(I2CPort port) { - LLC.init(port); - } - - /** Send a packet. - * @param packet the bytes to send - * @param len the number of bytes to send - * @return true if the send was successful, else false - */ - public boolean sendPacket(byte [] packet, int len) { - synchronized (this) { - boolean res = LLC.sendBytes(packet, len); - Delay.msDelay(100); - return res; - } - } - - /** Receive a packet. - * @param buffer the buffer to receive the packet into - * @return the number of bytes received - */ - public int receivePacket(byte [] buffer) { - gotPacket = false; - for(int i=0;i 0) return true; - while (lowerHandler.isPacketAvailable()) { - int len = lowerHandler.receivePacket(inPacket); - int sum = 0; - for(int i=0; i

    - * Motor regulation is not specified in this interface as it may be difficult to determine the accurate length per time - * (ie. mm/sec) rate due to encoder tick granularity of the linear actuator. It is up to the implementor to decide if the - * move() and moveTo() methods should produce regulated movement. - * - * @see lejos.hardware.device.LnrActrFirgelliNXT - * @author Kirk P. Thompson - */ -public interface LinearActuator extends Encoder { - /** - * Set the power level 0%-100% to be applied to the actuator motor where 0% is no movement and 100% is full speed. - * @param power new motor power 0-100% - */ - public void setPower(int power); - - /** - * Returns the current actuator motor power setting. - * @return current power 0-100% - */ - public int getPower(); - - /** The actuator should retract (negative distance value) or extend (positive distance value) - * in encoder ticks distance. The distance is specified to be relative to the actuator shaft position - * at the time of calling this method. The absolute unit per encoder tick is device-dependent and should be specified in the - * implementation documentation. - *

    - * Stall detection needs to be implemented to stop the actuator in the event of an actuator motor stall condition. - *

    - * If immediateReturn is true, this method should not block and return immediately. The actuator stops when the - * stroke distance is met or a stall is detected. - * @param distance The distance to move the actuator shaft - * @param immediateReturn true returns immediately, false waits for the action to complete (or a stall) - */ - public void move(int distance, boolean immediateReturn); - - /** The actuator should move to absolute position in encoder ticks. The position of the actuator - * shaft on startup should be zero. The position of the actuator shaft should be set to zero when - * resetTachoCount() is called. - * @param position The absolute shaft position in encoder ticks. - * @param immediateReturn true returns immediately, false waits for the action to complete (or a stall) - */ - public void moveTo(int position, boolean immediateReturn); - - /**Return true if the actuator is in motion due to a move() or moveTo() order. - * @return true if the actuator is in motion. false otherwise. - */ - public boolean isMoving(); - - /** - * Returns true if a move() or moveTo() order ended due to a stalled motor. This should - * behave like a latch where the - * reset of the stall status is done on a new move() or moveTo() order. - * @return true if actuator motor stalled during an move() or moveTo() order. - * false otherwise. - */ - public boolean isStalled(); - - /** - * Cause the actuator to stop immediately and resist any further motion. Cancel any move() or - * moveTo()orders in progress. - */ - public void stop(); - - /**Returns the absolute tachometer (encoder) position of the actuator shaft. The zero position of the actuator shaft is where - * resetTachoCount() was last called or the position of the shaft when instantiated. - * - * @return tachometer count in encoder ticks. - */ - public int getTachoCount(); - - /**Reset the tachometer (encoder) count to zero at the current actuator position. - */ - public void resetTachoCount(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/MirrorMotor.java b/ev3classes/src/main/java/lejos/robotics/MirrorMotor.java deleted file mode 100644 index b62b3b5..0000000 --- a/ev3classes/src/main/java/lejos/robotics/MirrorMotor.java +++ /dev/null @@ -1,188 +0,0 @@ -package lejos.robotics; - -/** - *

    This class returns a motor that rotates in the reverse direction of a regular motor. All tachometer - * readings are also reversed.

    - * - *

    Use the factory method MirrorMotor.invertMotor(RegulatedMotor) to retrieve an inverted motor.

    - * - * @author BB - * - */ -public class MirrorMotor implements RegulatedMotor, RegulatedMotorListener { - - private RegulatedMotor regMotor; - private RegulatedMotorListener regListener; - - /** - * Returns an inverted RegulatedMotor. - * @param motor A RegulatedMotor, such as Motor.A. - * @return An inverted RegulatedMotor. - */ - public static RegulatedMotor invertMotor(RegulatedMotor motor) { - if(motor instanceof MirrorMotor) { - ((MirrorMotor) motor).regMotor.addListener(((MirrorMotor) motor).regListener); - return ((MirrorMotor) motor).regMotor; - } - return new MirrorMotor(motor); - } - - /** - * Returns an inverted EncoderMotor. - * @param motor An EncoderMotor, such as NXTMotor. - * @return An inverted EncoderMotor. - */ - public static EncoderMotor invertMotor(EncoderMotor motor) { - if(motor instanceof ReversedEncoderMotor) { - return ((ReversedEncoderMotor) motor).encoderMotor; - } - return new ReversedEncoderMotor(motor); - } - - private MirrorMotor(RegulatedMotor motor) { - // Make motor listener this regListener - regListener = motor.removeListener(); // OK if listener is null - // Need to add this to motor listener - motor.addListener(this); - this.regMotor = motor; - } - - public void addListener(RegulatedMotorListener listener) { - // Listener needs to be reversed too. - regMotor.addListener(this); - this.regListener = listener; - } - - public RegulatedMotorListener removeListener() { - RegulatedMotorListener old = regListener; - regListener = null; - regMotor.removeListener(); - return old; - } - - public void flt(boolean immediateReturn) { - regMotor.flt(immediateReturn); - } - - public int getLimitAngle() { - return -regMotor.getLimitAngle();// REVERSED - } - - public float getMaxSpeed() { - return regMotor.getMaxSpeed(); - } - - public int getSpeed() { - return regMotor.getSpeed(); - } - - public boolean isStalled() { - return regMotor.isStalled(); - } - - public void rotate(int angle) { - this.rotate(angle, false); - } - - public void rotate(int angle, boolean immediateReturn) { - regMotor.rotate(-angle, immediateReturn);// REVERSED - } - - public void rotateTo(int angle) { - this.rotateTo(angle, false); - } - - public void rotateTo(int angle, boolean immediateReturn) { - regMotor.rotateTo(-angle, immediateReturn);// REVERSED - } - - public void setAcceleration(int acceleration) { - regMotor.setAcceleration(acceleration); - } - - public void setSpeed(int speed) { - regMotor.setSpeed(speed); - } - - public void setStallThreshold(int error, int time) { - regMotor.setStallThreshold(error, time); - } - - public void stop(boolean immediateReturn) { - regMotor.stop(immediateReturn); - } - - public void waitComplete() { - regMotor.waitComplete(); - } - - public void backward() { - regMotor.forward();// REVERSED - } - - public void flt() { - this.flt(false); - } - - public void forward() { - regMotor.backward(); // REVERSED - } - - public boolean isMoving() { - return regMotor.isMoving(); - } - - public void stop() { - regMotor.stop(false); - } - - public int getRotationSpeed() { - return regMotor.getRotationSpeed(); - } - - public int getTachoCount() { - return -regMotor.getTachoCount();// REVERSED - } - - public void resetTachoCount() { - regMotor.resetTachoCount(); - } - - public void rotationStarted(RegulatedMotor motor, int tachoCount, - boolean stalled, long timeStamp) { - if(regListener!=null) - regListener.rotationStarted(this, -tachoCount, stalled, timeStamp); - } - - public void rotationStopped(RegulatedMotor motor, int tachoCount, - boolean stalled, long timeStamp) { - if(regListener!=null) - regListener.rotationStopped(this, -tachoCount, stalled, timeStamp); - } - - @Override - public void close() { - regMotor.close(); - } - - @Override - public void synchronizeWith(RegulatedMotor[] syncList) - { - regMotor.synchronizeWith(syncList); - - } - - @Override - public void startSynchronization() - { - regMotor.startSynchronization(); - - } - - @Override - public void endSynchronization() - { - regMotor.endSynchronization(); - - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/PressureDetector.java b/ev3classes/src/main/java/lejos/robotics/PressureDetector.java deleted file mode 100644 index 0798ebf..0000000 --- a/ev3classes/src/main/java/lejos/robotics/PressureDetector.java +++ /dev/null @@ -1,17 +0,0 @@ -package lejos.robotics; - -/** - * Interface for pressure sensors. - * - * @author Lawrie Griffiths - * - */ -public interface PressureDetector { - - /** - * Get the pressure reading in kilopascals - * - * @return the pressure in kPa - */ - public float getPressure(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/RangeFinder.java b/ev3classes/src/main/java/lejos/robotics/RangeFinder.java deleted file mode 100644 index b70ea68..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RangeFinder.java +++ /dev/null @@ -1,23 +0,0 @@ -package lejos.robotics; - -/** - * Abstraction for a range finder sensor that returns the distance to the nearest object - * @see lejos.robotics.RangeScanner - * @author Lawrie Griffiths - */ -public interface RangeFinder { - /** - * Get the range to the nearest object - * - * @return the distance to the nearest object - */ - public float getRange(); - - /** - * If the sensor is capable, this method returns multiple range values from a single scan. Sensors that can only - * return a single value should return an array containing a single value. - * - * @return an array of ranges, ordered from closest to farthest. - */ - public float [] getRanges(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/RangeFinderAdapter.java b/ev3classes/src/main/java/lejos/robotics/RangeFinderAdapter.java deleted file mode 100644 index 151ecfa..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RangeFinderAdapter.java +++ /dev/null @@ -1,25 +0,0 @@ -package lejos.robotics; - -import lejos.robotics.filter.AbstractFilter; - -public class RangeFinderAdapter extends AbstractFilter implements RangeFinder{ - private final float[] buf; - - public RangeFinderAdapter(SampleProvider source) { - super(source); - buf=new float[sampleSize]; - } - - @Override - public float getRange() { - fetchSample(buf,0); - return buf[0] * 100; - } - - @Override - public float[] getRanges() { - float[] sample=new float[sampleSize]; - fetchSample(sample,0); - return sample; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/RangeReading.java b/ev3classes/src/main/java/lejos/robotics/RangeReading.java deleted file mode 100644 index 0898ae7..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RangeReading.java +++ /dev/null @@ -1,46 +0,0 @@ -package lejos.robotics; - -/** - * Represent a single range reading - */ -public class RangeReading { - private float range, angle; - - /** - * Create the reading - * - * @param angle the angle relative to the heading - * @param range the range reading - */ - public RangeReading(float angle, float range) { - this.range = range; - this.angle = angle; - } - - /** - * Get the range reading - * - * @return the range reading - */ - public float getRange() { - return range; - } - - /** - * Get the angle of the range reading - * - * @return the angle relative to the robot heading - */ - public float getAngle() { - return angle; - } - - /** - * Test if reading is invalid - * - * @return true iff the reading is invalid - */ - public boolean invalidReading() { - return range < 0; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/RangeReadings.java b/ev3classes/src/main/java/lejos/robotics/RangeReadings.java deleted file mode 100644 index e11c7b1..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RangeReadings.java +++ /dev/null @@ -1,121 +0,0 @@ -package lejos.robotics; - -import java.io.*; -import java.util.ArrayList; - -/** - * Represents a set of range readings. - * - * @author Lawrie Griffiths - */ -public class RangeReadings extends ArrayList implements Transmittable { - - - public RangeReadings(int numReadings) { - super(numReadings); - for(int i=0;i - * iff immediateReturn is true, method returns immediately and the motor stops by itself
    - * If any motor method is called before the limit is reached, the rotation is canceled. - * When the angle is reached, the method isMoving() returns false;
    - * - * @param angle through which the motor will rotate - * @param immediateReturn iff true, method returns immediately, thus allowing monitoring of sensors in the calling thread. - * - * @see RegulatedMotor#rotate(int, boolean) - */ - void rotate(int angle, boolean immediateReturn); - - /** - * Causes motor to rotate by a specified angle. The resulting tachometer count should be within +- 2 degrees on the NXT. - * This method does not return until the rotation is completed. - * - * @param angle by which the motor will rotate. - * - */ - void rotate(int angle); - - - /** - * Causes motor to rotate to limitAngle;
    - * Then getTachoCount should be within +- 2 degrees of the limit angle when the method returns - * @param limitAngle to which the motor will rotate, and then stop (in degrees). Includes any positive or negative int, even values > 360. - */ - public void rotateTo(int limitAngle); - - /** - * causes motor to rotate to limitAngle;
    - * if immediateReturn is true, method returns immediately and the motor stops by itself
    - * and getTachoCount should be within +- 2 degrees if the limit angle - * If any motor method is called before the limit is reached, the rotation is canceled. - * When the angle is reached, the method isMoving() returns false;
    - * @param limitAngle to which the motor will rotate, and then stop (in degrees). Includes any positive or negative int, even values > 360. - * @param immediateReturn iff true, method returns immediately, thus allowing monitoring of sensors in the calling thread. - */ - public void rotateTo(int limitAngle,boolean immediateReturn); - - /** - * Return the limit angle (if any) - * @return the current limit angle - */ - public int getLimitAngle(); - - /** - * Set motor speed. As a rule of thumb 100 degrees per second are possible for each volt on an NXT motor. Therefore, - * disposable alkaline batteries can achieve a top speed of 900 deg/sec, while a rechargable lithium battery pack can achieve - * 740 deg/sec. - * - * @param speed in degrees per second. - */ - void setSpeed(int speed); - - /** - * Returns the current motor speed. - * - * @return motor speed in degrees per second - */ - int getSpeed(); - - /** - * Returns the maximum speed that can be maintained by the regulation system based upon the - * current state of the battery. - * - * @return the maximum speed of the Motor in degrees per second. - */ - float getMaxSpeed(); - - /** - * returns true if motor is stalled - * @return true if stalled - */ - boolean isStalled(); - - /** - * Set the parameters for detecting a stalled motor. A motor will be recognized as - * stalled if the movement error (the amount the motor lags the regulated position) - * is greater than error for a period longer than time. - * - * @param error The error threshold - * @param time The time that the error threshold needs to be exceeded for. - */ - void setStallThreshold(int error, int time); - - /** - * Set the required rate of acceleration degrees/s/s - * @param acceleration - */ - void setAcceleration(int acceleration); - /** - * Specify a set of motors that should be kept in synchronization with this one. - * The synchronization mechanism simply ensures that operations between a startSynchronization - * call and an endSynchronization call will all be executed at the same time (when the - * endSynchronization method is called). This is all that is needed to ensure that motors - * will operate in a synchronized fashion. The start/end methods can also be used to ensure - * that reads of the motor state will also be consistent. - * @param syncList an array of motors to synchronize with. - */ - public void synchronizeWith(RegulatedMotor[] syncList); - - /** - * Begin a set of synchronized motor operations - */ - public void startSynchronization(); - - /** - * Complete a set of synchronized motor operations. - */ - public void endSynchronization(); - - /** - * Close the port, the port can not be used after this call. - */ - public void close(); - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/RegulatedMotorListener.java b/ev3classes/src/main/java/lejos/robotics/RegulatedMotorListener.java deleted file mode 100644 index e629009..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RegulatedMotorListener.java +++ /dev/null @@ -1,21 +0,0 @@ -package lejos.robotics; - -/** - * This interface defines a listener that is notified of the tachometer when the motor starts and stops rotating. - * It doesn't matter if start/stop rotation is caused by Motor.forward() or Motor.rotateTo(), or if the rotation - * is terminated by rotationTo() finishing naturally or by stop(). If the motor state changes directly from forward() - * to backward(), then a stop() is called in between which results in a new rotationEnded() and rotationStarted() notification. - */ -public interface RegulatedMotorListener { - /** - * Called when the motor starts rotating. - */ - public void rotationStarted(RegulatedMotor motor,int tachoCount, boolean stalled, long timeStamp); - - /** - * Called when the motor stops rotating. This includes both Motor.stop() which locks the shaft, and - * Motor.flt() in which the shaft floats freely after power is cut to the motor. Beware: In the second case, it's possible - * the tachomoter reading will continue changing after notification. - */ - public void rotationStopped(RegulatedMotor motor,int tachoCount, boolean stalled,long timeStamp); -} diff --git a/ev3classes/src/main/java/lejos/robotics/ReversedEncoderMotor.java b/ev3classes/src/main/java/lejos/robotics/ReversedEncoderMotor.java deleted file mode 100644 index e0574f0..0000000 --- a/ev3classes/src/main/java/lejos/robotics/ReversedEncoderMotor.java +++ /dev/null @@ -1,46 +0,0 @@ -package lejos.robotics; - -class ReversedEncoderMotor implements EncoderMotor { - - EncoderMotor encoderMotor; - - ReversedEncoderMotor(EncoderMotor motor) { - this.encoderMotor = motor; - } - - public int getPower() { - return encoderMotor.getPower(); - } - - public void setPower(int power) { - encoderMotor.setPower(power); - } - - public void backward() { - encoderMotor.forward(); - } - - public void flt() { - encoderMotor.flt(); - } - - public void forward() { - encoderMotor.backward(); - } - - public boolean isMoving() { - return encoderMotor.isMoving(); - } - - public void stop() { - encoderMotor.stop(); - } - - public int getTachoCount() { - return -encoderMotor.getTachoCount(); - } - - public void resetTachoCount() { - encoderMotor.resetTachoCount(); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/RotatingRangeScanner.java b/ev3classes/src/main/java/lejos/robotics/RotatingRangeScanner.java deleted file mode 100644 index cb95ac3..0000000 --- a/ev3classes/src/main/java/lejos/robotics/RotatingRangeScanner.java +++ /dev/null @@ -1,99 +0,0 @@ -package lejos.robotics; - -import lejos.utility.Delay; - -/** - * Implementation of RangeScanner with a rotating ultrasonic sensor or other range finder - * @author Roger Glassey - */ -public class RotatingRangeScanner implements RangeScanner -{ - - /** - * The constructor specifies the motor and range finder used - * @param head the motor that rotates the sensor - * @param rangeFinder the range finder - */ - public RotatingRangeScanner(RegulatedMotor head, RangeFinder rangeFinder) - { - this(head,rangeFinder,1); - } - - public RotatingRangeScanner(RegulatedMotor head, RangeFinder rangeFinder, int gearRatio) { - this.head = head; - this.rangeFinder = rangeFinder; - this.gearRatio = gearRatio; - head.resetTachoCount(); - } - - /** - * Set the gear ratio - * - * @param gearRatio the gear ratio - */ - public void setGearRatio(int gearRatio) - { - this.gearRatio = gearRatio; - } - - /** - * Set the head motor - * - * @param motor the head motor - */ - public void setHeadMotor(RegulatedMotor motor) { - head = motor; - } - - /** - * Returns a set of Range Readings taken the angles specified. - * @return the set of range values - */ - public RangeReadings getRangeValues() - { - if (readings == null || readings.getNumReadings() != angles.length) - { - readings = new RangeReadings(angles.length); - } - - for (int i = 0; i < angles.length; i++) - { - head.rotateTo(((int) angles[i]) * gearRatio); - Delay.msDelay(50); - float range = rangeFinder.getRange() + ZERO; - if (range > MAX_RELIABLE_RANGE_READING) - { - range = -1; - } - readings.setRange(i, angles[i], range); - } - head.rotateTo(0); - return readings; - } - - /** - * set the angles to be used by the getRangeValues() method - * @param angles - */ - public void setAngles(float[] angles) - { - this.angles = angles.clone(); - } - -/** - * returns the rangeFinder - allows other objects to get a range value. - * @return the range finder - */ - public RangeFinder getRangeFinder() - { - return rangeFinder; - } - - protected final int MAX_RELIABLE_RANGE_READING = 180; - protected final int ZERO = 2;// correction of sensor zero - protected RangeReadings readings; - protected RangeFinder rangeFinder; - protected RegulatedMotor head; - protected float[] angles ={0,90};// default - protected int gearRatio; -} diff --git a/ev3classes/src/main/java/lejos/robotics/SampleProvider.java b/ev3classes/src/main/java/lejos/robotics/SampleProvider.java deleted file mode 100644 index 67d41b0..0000000 --- a/ev3classes/src/main/java/lejos/robotics/SampleProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -package lejos.robotics; - -/** Abstraction for classes that fetch samples from a sensor and classes that are able to process samples.
    - * A sample is a measurement taken by a sensor at a single moment in time. - * A sample can have one or more elements. The number of elements in a sample depends on the sensor (and sensor mode). - *
    - * - * Sample providers comply with standards. - *
      - *
    • - * Sample providers use standard units.
      - *
        - *
      • Length in meters
      • - *
      • Angle in degrees
      • - *
      • Temperature in degrees celcius
      • - *
      • Pressure in Pascal
      • - *
      • Speed in m/s
      • - *
      • Acceleration in m/s^2
      • - *
      • etc...
      • - *
      - *
    • - *
    • - * When there is no clear unit a sample provider use normalized values in the range between 0 and 1. - *
    • - *
    • - * Sample providers that measure spatial data use a right handed cartesian coordinate system with the X-axis pointing forwards, - * the Y-axis pointing to the left and the Z-axis pointing up. - * (The plug of a sensor is always on its back.) - *
    • - *
    • - * A positive rotation of a mobile robot is a counterclockwise rotation. - *
    • - *
    • - * If a sample provider measures spatial data over more than one axis, the order of the elements in a sample corresponds with the X,Y and Z axis. - *
    • - *
    - * @author Aswin Bouwmeester - * - */ -public interface SampleProvider { - - /** Returns the number of elements in a sample.
    - * The number of elements does not change during runtime. - * @return - * the number of elements in a sample - */ - public int sampleSize(); - - /** Fetches a sample from a sensor or filter. - * @param sample - * The array to store the sample in. - * @param offset - * The elements of the sample are stored in the array starting at the offset position. - */ - public void fetchSample(float[] sample, int offset); -} diff --git a/ev3classes/src/main/java/lejos/robotics/Servo.java b/ev3classes/src/main/java/lejos/robotics/Servo.java deleted file mode 100644 index fd458fb..0000000 --- a/ev3classes/src/main/java/lejos/robotics/Servo.java +++ /dev/null @@ -1,61 +0,0 @@ -package lejos.robotics; - -/** - * Abstraction for a range-limited servo motor. - * - * @author Kirk P. Thompson - */ -public interface Servo { - /** - * Sets the rotational position (angle) of a ranged servo. - * - * @param angle the target angle in degrees - * @see #getAngle - * @see #setRange - */ - public void setAngle(float angle); - - /** - * Gets the rotational position (angle) of a ranged servo. - * - * @return the angle in degrees - * @see #setAngle - */ - public float getAngle(); - - /** - * Set the PWM pulse width for the servo. This must be in the range defined for the servo. This method allows manipulation - * of the servo position based on absolute pulse widths in microseconds. - *

    - * A servo pulse of 1500 microseconds (1.5 ms) width will typically set the servo to its "neutral" position. This is the - * "standard pulse servo mode" used by all hobby analog servos. - * - * @param microSeconds The pulse width time in microseconds - */ - public void setpulseWidth(int microSeconds); - - /** - * Get the current PWM pulse width for the servo. - * - * @return The pulse width time in microseconds - */ - public int getpulseWidth(); - - /**Set the allowable pulse width operating range of this servo in microseconds and the total travel range to allow - * the use of angle-based parameters to control the servo. - *

    - * This information - * is used to calculate ansolute angles used by the setAngle() and getAngle() methods. - * The midpoint - * of the pulse width operating range should normally be 1500 microseconds so the range extents should reflect this. - *

    - * This information must reflect the appropriate specifications and/or empirical characterization data of the specific - * servo used for the setAngle() method to be able to position the servo accurately. - * - * @param microsecLOW The low end of the servos response/operating range in microseconds - * @param microsecHIGH The high end of the servos response/operating range in microseconds - * @param travelRange The total mechanical travel range of the servo in degrees - * @see #setAngle - */ - public void setRange (int microsecLOW, int microsecHIGH, int travelRange); -} diff --git a/ev3classes/src/main/java/lejos/robotics/Tachometer.java b/ev3classes/src/main/java/lejos/robotics/Tachometer.java deleted file mode 100644 index 3a591b6..0000000 --- a/ev3classes/src/main/java/lejos/robotics/Tachometer.java +++ /dev/null @@ -1,19 +0,0 @@ -package lejos.robotics; - -/** - * Abstraction for a Tachometer, which monitors speed of the encoder. - * - * @author BB - * - */ -public interface Tachometer extends Encoder { - - - /** - * Returns the actual speed. - * - * @return speed in degrees per second, negative value means motor is rotating backward - */ - int getRotationSpeed(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/Touch.java b/ev3classes/src/main/java/lejos/robotics/Touch.java deleted file mode 100644 index f954214..0000000 --- a/ev3classes/src/main/java/lejos/robotics/Touch.java +++ /dev/null @@ -1,16 +0,0 @@ - -package lejos.robotics; - -/** - * Abstraction for touch sensors - * - * @author Andy - * - */ -public interface Touch { - /** - * Check if the sensor is pressed. - * @return true if sensor is pressed, false otherwise. - */ - public boolean isPressed(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/TouchAdapter.java b/ev3classes/src/main/java/lejos/robotics/TouchAdapter.java deleted file mode 100644 index 0cc4275..0000000 --- a/ev3classes/src/main/java/lejos/robotics/TouchAdapter.java +++ /dev/null @@ -1,19 +0,0 @@ -package lejos.robotics; - -import lejos.hardware.sensor.*; - -public class TouchAdapter implements Touch{ - private final float[] buf; - SensorMode source; - - public TouchAdapter(BaseSensor touchSensor) { - this.source = touchSensor.getMode("Touch"); - buf=new float[source.sampleSize()]; - } - - @Override - public boolean isPressed() { - source.fetchSample(buf,0); - return (buf[0] > 0); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/Transmittable.java b/ev3classes/src/main/java/lejos/robotics/Transmittable.java deleted file mode 100644 index 3a6fc9a..0000000 --- a/ev3classes/src/main/java/lejos/robotics/Transmittable.java +++ /dev/null @@ -1,11 +0,0 @@ -package lejos.robotics; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -public interface Transmittable { - public void dumpObject(DataOutputStream dos) throws IOException; - - public void loadObject(DataInputStream dis) throws IOException; -} diff --git a/ev3classes/src/main/java/lejos/robotics/chassis/Chassis.java b/ev3classes/src/main/java/lejos/robotics/chassis/Chassis.java deleted file mode 100644 index 912e052..0000000 --- a/ev3classes/src/main/java/lejos/robotics/chassis/Chassis.java +++ /dev/null @@ -1,264 +0,0 @@ -package lejos.robotics.chassis; - -import lejos.robotics.localization.PoseProvider; -import lejos.robotics.navigation.Move; -import lejos.utility.Matrix; - - -/** - * Represents the chassis of a robot. The Chassis provides a control system for driving a mobile robot. - * - *

    How to use a Chassis object
    - * The primary goal of the chassis is to make a robot move. - * This can be done in two different ways.
    - * One way is by specifying the speed at which a chassis should move, this is called velocity mode. - * The primary methods for this mode are {@link #setVelocity(double, double) setVelocity} and {@link #stop() stop} .
    - * The second way is by specifying the kind of move the chassis should make, this is called move mode. - * The primary methods for this mode are {@link #arc(double, double) arc}, {@link #rotate(double) rotate} and {@link #travel(double) travel}. - * The move mode methods use speed and acceleration parameters that have to be specified beforehand using {@link #setSpeed(double, double) setSpeed} - * and {@link #setAcceleration(double, double) setAcceleration}.
    - * Depending on the application one of these modes will suit better, but the modes can be used together.

    - * - *

    Understanding linear and angular velocity and acceleration
    - * Within the context of the chassis speed and acceleration have both a linear and an angular component. - * The linear component describes the forward speed (or acceleration) of the robot. - * It specifies the speed of the robot traveling a straight line using the same unit as was used to specify the wheels of the chassis. - * The linear speed is always the speed of the center of the robot, when driving an arc the forward speed of the outer wheel exceeds the speed of the center of the chassis.
    - * The angular component of speed (or acceleration) describes how fast the robot is turning around its center. This is always expressed in degrees/second.
    - * When using velocity based methods the chassis combines both speed elements to calculate the speed of each of the wheels. - * This results in a movement of the robot that can be anything from a rotation around its center (when the linear speed component is zero) - * to a curve (when both components are not zero) to a straight line (when the angular component is zero).
    - * When using move based methods the speed settings are used to calculate the speed at which a move can be made. - * If, for example, a very low angular speed has been set then this influences the speed at which an arc will be driven. - * The chassis makes sure the forward speed will be such that the angular speed will not exceed the specified setting.

    - * - *

    Speed transitions
    - * To prevent jerky movements of the robot the velocity based methods {@link #setVelocity(double, double) setVelocity} and {@link #stop() stop} - * ensure smooth speed transitions using the acceleration settings that are specified using the - * {@link #setAcceleration(double, double) setAcceleration} method. - * This means that each of the wheels of the chassis takes exactly the same time to reach final speed, - * no matter what the speed of the wheels was at the moment the travel method was issued.
    - * The move based methods do not know these smooth transitions. - * These methods assume that the robot is at stand still when the method is issued and that the robot is at stand still again when the move ends. - * (Without this assumption it cannot be guaranteed that the trajectory of the robot has indeed the same shape as the method name implies.) - * - *

    Odometry
    - * The chassis can provide a {@link lejos.robotics.localization.PoseProvider PoseProvider} that keeps track of the robots pose using the encoders of the wheels. - * The object is provided by the {@link #getPoseProvider() getPoseProvider} method.

    - * - * @author Aswin Bouwmeester - * - */ -public interface Chassis { - - /** Gets the setting for linear speed as is used in moveTo, Arc, and Rotate methods - * @return - * Linear speed in robot units/second - */ - public double getLinearSpeed(); - - /** Sets the linear speed as is used in travel, arc, and rotate methods - * @param linearSpeed - * Linear speed in robot units/second - */ - public void setLinearSpeed(double linearSpeed); - - /** Gets the setting for angular speed as is used in travel, arc, and rotate methods - * @return - * Angular speed in degrees/second. - */ - public double getAngularSpeed(); - - /** Sets the angular speed as is used in travel, arc, and rotate methods - * @param angularSpeed - * Angular speed in degrees/second. - */ - public void setAngularSpeed(double angularSpeed); - - /** Gets the setting for linear acceleration as is used in travel, arc, rotate and setvelocity methods - * @return - * Linear acceleration in robot units/second^2 - */ - public double getLinearAcceleration(); - - /** Sets the linear acceleration as is used in travel, arc, rotate and setvelocity methods - * @param linearAcceleration - * Linear acceleration in robot units/second^2 - */ - public void setLinearAcceleration(double linearAcceleration); - - /** Gets the setting for angular acceleration as is used in travel, arc, rotate and setvelocity methods - * @return - * Angular acceleration in degrees/second^2. - */ - public double getAngularAcceleration(); - - /** Sets the angular acceleration as is used in travel, arc, rotate and setvelocity methods - * @param angularAcceleration - * Angular Acceleration in degrees/second^2. - */ - public void setAngularAcceleration(double angularAcceleration); - - /** Returns a matrix containing the current speed of the robot. - * @return - * A matrix (3x1) containing the current speed of the robot. First row contains linear speed, second row contains direction of linear speed, third row contains angular speed. - */ - public Matrix getCurrentSpeed(); - - /** - * Returns true if the robot is moving. - * - * @return true if the robot is moving - */ - public boolean isMoving(); - - /** - * Makes the robot stop and returns immediately. - */ - public void stop(); - - - /** Moves the chassis with specified speed - * @param linearSpeed - * linear component of the robot speed, expressed in the same unit as the wheel diameter. - * @param angularSpeed - * angular component of the robot speed expressed in degrees/second. - */ - public void setVelocity(double linearSpeed, double angularSpeed); - - /** Moves a holonomic chassis with specified speed - * @param linearSpeed - * linear component of the robot speed, expressed in the same unit as the wheel diameter. - * @param direction - * The direction of the linear speed - * @param angularSpeed - * angular component of the robot speed expressed in degrees/second. - */ - public void setVelocity(double linearSpeed, double direction, double angularSpeed); - - /** Moves a holonomic robot with the specified speed.
    - * The method will throw an exception when issued on a differential chassis. - * @param xSpeed - * speed along the robots x-axis - * @param ySpeed - * speed along the robots y-axis - * @param angularSpeed - * angular component of the robot speed expressed in degrees/second. - */ - public void travelCartesian(double xSpeed, double ySpeed, double angularSpeed ); - - /** Moves the chassis the specified distance - * @param linear - * linear component of the robot speed, expressed in the same unit as the wheel diameter. - */ - public void travel(double linear); - - /** Moves the chassis in an arc - * @param radius - * the radius of the arc. - * A positive radius means the center of the arc is on the left side of the robot, - * the center of a negative arc is on the right side of the robot. Infinite radius is not allowed. - * A radius of 0 makes the robot spin in place. - * - * @param angle - * The number of degrees of the arc. A positive number of degrees makes the robot go forward, - * a negative number makes it go backward. - */ - public void arc(double radius, double angle); - - /** - * Returns the maximum speed of the robot. - * - * @return Speed in robot units - */ - public double getMaxLinearSpeed(); - - /** - * Returns how fast the robot can rotate. - * - * @return Speed in degrees / second - */ - public double getMaxAngularSpeed(); - - /** - * Blocks while the chassis is moving, returns when all wheels have stopped - * (including stops caused by stalls) - */ - public void waitComplete(); - - /** - * Returns true if at least one of the wheels is stalled - * - * @return true if at least one of the wheels is stalled - */ - public boolean isStalled(); - - /** - * Returns the smallest possible radius this chassis is able turn - * - * @return radius in robot units - */ - public double getMinRadius(); - - /** Sets the speed of the chassis for the moveTo method - * - * @param linearSpeed - * linear component of the robot speed, expressed in the same unit as the wheel diameter. - * @param angularSpeed - * angular component of the robot speed expressed in degrees/second. - */ - public void setSpeed(double linearSpeed, double angularSpeed); - - /** Sets the acceleration of the chassis for the moveTo and travel methods - * @param forwardAcceleration - * linear component of the robot acceleration, expressed in robot units/second^2. - * @param angularAcceleration - * angular component of the robot speed expressed acceleration, expressed in degrees/second^2. - */ - public void setAcceleration(double forwardAcceleration, double angularAcceleration); - - /** Returns an Pose provider that uses odometry to keep track of the pose of the chassis - * @return an Pose provider that uses odometry to keep track of the pose of the chassis - */ - public PoseProvider getPoseProvider(); - - /** Method used by the MovePilot to tell the chassis that a new move has started. This method is used in conjuction with the getDisplacement method. - * - */ - public void moveStart(); - - /** Method used by the MovePilot to update a move object that describes the move executed since the last call to startMove.

    - * This method is only to be used by applications that apply just moves that meet the following conditions:

      - *
    • The move must start and end with the robot being motionless
    • - *
    • The speed ratio between the wheels must be constant during the move
    • - *
    - * - * @param move - * The move object to update - */ - public Move getDisplacement(Move move); - - /** Rotates the chassis for the specified number of degrees - * @param angular - */ - void rotate(double angular); - - /** Returns the linear component of the current speed of the robot - * @return - * linear speed in robot units/second - */ - double getLinearVelocity(); - - /** Returns the current direction of the linear speed component of the robot - * @return - * direction in degrees - */ - double getLinearDirection(); - - /** Returns the angular component of the current speed of the robot - * @return - * Angular speed in degrees/second - */ - double getAngularVelocity(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/chassis/Wheel.java b/ev3classes/src/main/java/lejos/robotics/chassis/Wheel.java deleted file mode 100644 index 3130d33..0000000 --- a/ev3classes/src/main/java/lejos/robotics/chassis/Wheel.java +++ /dev/null @@ -1,19 +0,0 @@ -package lejos.robotics.chassis; - -import lejos.robotics.RegulatedMotor; -import lejos.utility.Matrix; - -public interface Wheel { - - /** Returns the x,y and r factors to calculate motor speed from wheel linear and angular speed.

    - * The factors form the row of a forward matrix - * @return the factors as a matrix - */ - public Matrix getFactors(); - - public RegulatedMotor getMotor(); - - - - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/chassis/WheeledChassis.java b/ev3classes/src/main/java/lejos/robotics/chassis/WheeledChassis.java deleted file mode 100644 index 6abc619..0000000 --- a/ev3classes/src/main/java/lejos/robotics/chassis/WheeledChassis.java +++ /dev/null @@ -1,866 +0,0 @@ -package lejos.robotics.chassis; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.localization.PoseProvider; -import lejos.robotics.navigation.Move; -import lejos.robotics.navigation.Pose; -import lejos.utility.Delay; -import lejos.utility.Matrix; - - -/** Represents the chassis of a wheeled robot. - *

    The WheeledChassis provides a control system for driving a mobile robot with motorized wheels. - * Both differential and holonomic robots can be represented by the WheeledChassis class.

    - * - *

    How to create a WheeledChassis object
    - * The constructor of the DifferentialChassis class accepts an array of Wheel objects. - * Each of the wheel objects describes one of the motorized wheels on the chassis. - * A Description of a wheel consists of its diameter, its position, its motor and the gear train between wheel and motor. - * Wheel objects can be created using a modeler class. A modeler for traditional wheel can be obtained using the {@link #modelWheel} method. - * A modeler for a holonomic wheel can be obtained using the {@link #modelHolonomicWheel} method.

    . - *

    - * This example creates a WheeledChassis for a differential robot. - *

    - * Wheel wheel1 = WheeledChassis.modelWheel(Motor.A, 81.6).offset(-70);
    - * Wheel wheel2 = WheeledChassis.modelWheel(Motor.D, 81.6).offset(70);
    - * Chassis chassis = new WheeledChassis(new Wheel[] { wheel1, wheel2 }, WheeledChassis.TYPE_DIFFERENTIAL);
    - * 
    - *

    - *

    - * This example creates a WheeledChassis for a holonomic robot. - *

    - *    Wheel wheel1 = WheeledChassis.modelHolonomicWheel(Motor.A, 48).polarPosition(0, 135).gearRatio(2);
    - *    Wheel wheel2 = WheeledChassis.modelHolonomicWheel(Motor.B, 48).polarPosition(120, 135).gearRatio(2);
    - *    Wheel wheel3 = WheeledChassis.modelHolonomicWheel(Motor.C, 48).polarPosition(240, 135).gearRatio(2);
    - *    Chassis chassis = new WheeledChassis(new Wheel[]{wheel1, wheel2, wheel3}, WheeledChassis.TYPE_HOLONOMIC);
    - * 
    - *

    - *

    Please note that a Chassis can have an unlimited number of motorized wheels but a differential robot - * needs at least two wheels and a holonomic robot needs at least three wheels.

    - * - *

    See also the {@link Chassis} interface.

    * - * @author Aswin Bouwmeester - * - */ -public class WheeledChassis implements Chassis { - protected static final int TACHOCOUNT=0; - protected static final int MAXSPEED=1; - protected static final int ROTATIONSPEED=2; - - public static final int TYPE_DIFFERENTIAL = 2; - public static final int TYPE_HOLONOMIC = 3; - final int nWheels; - /** - * The program adds a dummy wheel to a differential chassis. - * This dummy wheel makes it possible to use linear algebra on three elements (x, y, angle) - * for the differential chassis. The y value is always zero for a differential chassis. - */ - protected final int dummyWheels; - protected final RegulatedMotor[] motor; - protected double linearSpeed, angularSpeed, linearAcceleration, angularAcceleration; - - final protected Matrix forward; - final protected Matrix reverse; - protected RegulatedMotor master; - protected Matrix tachoAtMoveStart; - - final protected Matrix forwardAbs; - final protected Matrix reverseAbs; - protected Odometer odometer; - - - - public WheeledChassis(Wheel[] wheels, int dim) { - nWheels = wheels.length; - if (nWheels < dim ) throw new IllegalArgumentException(String.format("The chassis must have at least %d motorized wheels", dim)); - if (dim == TYPE_DIFFERENTIAL) dummyWheels =1; - else dummyWheels =0; - - // register the motors - motor = new RegulatedMotor[nWheels]; - for (int i = 0; i < nWheels; i++) { - motor[i] = wheels[i].getMotor(); - } - // Make the wheels synchronized - this.master = motor[0]; - RegulatedMotor[] sync = new RegulatedMotor[nWheels - 1]; - System.arraycopy(motor, 1, sync, 0, nWheels - 1); - master.synchronizeWith(sync); - - // create the forward forward matrix - forward = new Matrix(nWheels + dummyWheels, 3); - for (int row = 0; row < nWheels; row++) { - forward.setMatrix(row, row, 0, 2, wheels[row].getFactors()); - } - if (dummyWheels==1) { - forward.set(nWheels,0,0); - forward.set(nWheels,1,1); - forward.set(nWheels,2,0); - } - // create the reverse matrix - try { - reverse = forward.inverse(); - } - catch(RuntimeException e) { - throw new RuntimeException("Invalid wheel setup, this robot is not controlable. Check position of the wheels."); - } - - // create absolute versions of forward and reverse matrices (used for speed and acceleration that both are always positive). - forwardAbs = this.copyAbsolute(forward); - reverseAbs = this.copyAbsolute(reverse); - - // Give speed and acceleration some default values - double s = this.getMaxLinearSpeed(); - double a = this.getMaxAngularSpeed(); - setSpeed(s/2, a/2); - setAcceleration(s/2, a/2); - - // store position of tacho's - tachoAtMoveStart = getAttribute(TACHOCOUNT); - - } - - - @Override - public double getLinearSpeed() { - return linearSpeed; - } - - - @Override - public void setLinearSpeed(double linearSpeed) { - this.linearSpeed = linearSpeed; - } - - - @Override - public double getAngularSpeed() { - return angularSpeed; - } - - - @Override - public void setAngularSpeed(double angularSpeed) { - this.angularSpeed = angularSpeed; - } - - - @Override - public double getLinearAcceleration() { - return linearAcceleration; - } - - - @Override - public void setLinearAcceleration(double linearAcceleration) { - this.linearAcceleration = linearAcceleration; - } - - - @Override - public double getAngularAcceleration() { - return angularAcceleration; - } - - - @Override - public void setAngularAcceleration(double angularAcceleration) { - this.angularAcceleration = angularAcceleration; - } - - - public Matrix getForward() { - return forward.copy(); - } - - - public Matrix getReverse() { - return reverse.copy(); - } - - - @Override - public void setSpeed(double linearSpeed, double angularSpeed) { - if (linearSpeed <=0 || angularSpeed <=0) throw new IllegalArgumentException("Speed must be greater than 0"); - this.linearSpeed=linearSpeed; - this.angularSpeed = angularSpeed; - } - - @Override - public void setAcceleration(double linearAcceleration, double angularAcceleration) { - if (linearAcceleration <=0 || angularAcceleration <=0) throw new IllegalArgumentException("Acceleration must be greater than 0"); - this.linearAcceleration=linearAcceleration; - this.angularAcceleration = angularAcceleration; - } - - - // State - - @Override - public boolean isMoving() { - for (RegulatedMotor wheel : motor) { - if (wheel.isMoving()) { - return true; - } - } - return false; - } - - - @Override - public void waitComplete() { - for (RegulatedMotor wheel : motor) - wheel.waitComplete(); - } - - @Override - public boolean isStalled() { - for (RegulatedMotor wheel : motor) { - if (wheel.isStalled()) - return true; - } - return false; - } - - @Override - public double getMinRadius() { - return 0; - } - - @Override - public void stop() { - setVelocity(0, 0, 0); - } - - @Override - public void setVelocity(double linearSpeed, double angularSpeed) { - setVelocity(linearSpeed, 0, angularSpeed); - } - - public void travelCartesian(double xSpeed, double ySpeed, double angularSpeed) { - setVelocity(Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed), Math.atan2(ySpeed, xSpeed), angularSpeed); - } - - public synchronized void setVelocity(double linearSpeed, double direction, double angularSpeed) { - if (dummyWheels ==1 && (direction % 180 != 0) ) throw new RuntimeException("Invalid direction for differential a robot."); - // create matrices with speed and acceleration components using direction; - Matrix motorSpeed = forward.times(toCartesianMatrix(linearSpeed, Math.toRadians(direction), angularSpeed)); - Matrix motorAcceleration = forwardAbs.times(copyAbsolute(toCartesianMatrix(linearAcceleration, Math.toRadians(direction), angularAcceleration))); - Matrix currentMotorSpeed = (getAttribute(ROTATIONSPEED)); - - // calculate acceleration for each of the wheels. - // The goal is that all wheels take an even amount of time to reach final speed - - // Calculate difference between final speed and current speed - Matrix dif = motorSpeed.minus(currentMotorSpeed); - // Calculate how much time each wheel needs to reach final speed; - Matrix time = dif.arrayRightDivide(motorAcceleration); - // Find the longest time - double longestTime = getMax(time); - if (longestTime == 0) return; // Aha, no speed differences. Do nothing. - // Devide speed difference by the longest time to get acceleration for each wheel - dif = dif.timesEquals(1 / longestTime); - // Set the dynamics and execute motion - master.startSynchronization(); - for (int i = 0; i < nWheels; i++) { - motor[i].setAcceleration((int) dif.get(i, 0)); - motor[i].setSpeed((int) Math.abs(motorSpeed.get(i, 0))); - switch((int)Math.signum(motorSpeed.get(i, 0))) { - case -1: motor[i].backward(); break; - case 0: motor[i].stop(); break; - case 1: motor[i].forward(); break; - } - } - master.endSynchronization(); - } - - @Override - public void travel(double linear) { - if (Double.isInfinite(linear) ) { - setVelocity(Math.signum(linear) * linearSpeed,0); - } - else { - Matrix motorDelta = forward.times(toMatrix(linear, 0, 0)); - Matrix motorSpeed = forwardAbs.times(toMatrix(linearSpeed, 0, 0 )); - Matrix motorAcceleration = forwardAbs.times(toMatrix(linearAcceleration, 0, 0 )); - setMotors( motorDelta, motorSpeed, motorAcceleration); - } - } - - @Override - public void rotate(double angular) { - if (Double.isInfinite(angular) ) { - setVelocity(0, Math.signum(angular) * angularSpeed); - } - else { - Matrix motorDelta = forward.times(toMatrix(0, 0, angular)); - Matrix motorSpeed = forwardAbs.times(toMatrix(0, 0, angularSpeed )); - Matrix motorAcceleration = forwardAbs.times(toMatrix(0, 0, angularAcceleration )); - setMotors( motorDelta, motorSpeed, motorAcceleration); - } - } - - - @Override - public void arc (double radius, double angle) { - if (angle == 0) return; - // ratio between linear and angular speed that corresponds with the radius - double ratio = Math.abs(Math.PI * radius / 180 ); - - if (Double.isInfinite(angle)) { - // Decrease one of both speed components so that they have the calculated ratio and call travel method - if (ratio>1) - setVelocity(Math.signum(angle) * linearSpeed, 0, Math.signum(radius) * linearSpeed/ratio); - else - setVelocity(Math.signum(angle) * angularSpeed * ratio, 0, Math.signum(radius) * angularSpeed); - } - else if (radius == 0) { - rotate(angle); - return; - } - else if (Double.isInfinite(radius)) { - if (angle < 0) - travel(Double.POSITIVE_INFINITY); - else - travel(Double.NEGATIVE_INFINITY); - } - else { - // Matrix holding linear and angular distance matching the specified arc - Matrix displacement = toMatrix(Math.signum(angle) * 2 * Math.PI * Math.abs(radius) * Math.abs(angle) / 360 , 0, Math.signum(radius) * angle); - - Matrix tSpeed; - Matrix tAcceleration; - // Decrease one of both speed and acceleration components so that they have the calculated ratio - if (ratio > 1) { - tSpeed=toMatrix(linearSpeed, 0, linearSpeed / ratio); - tAcceleration=toMatrix(linearAcceleration, 0, linearAcceleration / ratio); - } - else { - tSpeed=toMatrix(angularSpeed * ratio, 0, angularSpeed ); - tAcceleration=toMatrix(angularAcceleration * ratio, 0, angularAcceleration ); - } - // calculate the displacement of the motors from robot displacement - Matrix motorDelta = forward.times(displacement); - // calculate the ratio between motor displacements when the largest displacement is set to 1; - Matrix mRatio = motorDelta.times(1 / this.getMax(motorDelta)); - // Calculate the speed of the fasted moving robot and from this - // calculated the speed of the other motors using the motor displacement ratio - Matrix motorSpeed = mRatio.times(getMax(forwardAbs.times(tSpeed))); - // repeat for acceleration - Matrix motorAcceleration = mRatio.times(getMax(forwardAbs.times(tAcceleration))); - setMotors( motorDelta, motorSpeed, motorAcceleration); - } - } - - /** Utility method to set distance, speed and acceleration for each motor - * @param motorDelta - * @param motorSpeed - * @param motorAcceleration - */ - protected synchronized void setMotors(Matrix motorDelta, Matrix motorSpeed, Matrix motorAcceleration) { - master.startSynchronization(); - for (int i = 0; i < nWheels; i++) { - motor[i].setAcceleration((int) motorAcceleration.get(i, 0)); - motor[i].setSpeed((int) motorSpeed.get(i, 0)); - motor[i].rotate((int) motorDelta.get(i, 0)); - } - master.endSynchronization(); - } - - - // Dynamics - @Override - public double getMaxLinearSpeed() { - Matrix motorSpeed = getAttribute(MAXSPEED); - - Matrix wheelSpeed = reverseAbs.times(motorSpeed); - return Math.sqrt(wheelSpeed.get(0, 0) * wheelSpeed.get(0, 0) + wheelSpeed.get(1, 0) * wheelSpeed.get(1, 0)); - } - - @Override - public double getMaxAngularSpeed() { - Matrix motorSpeed = getAttribute(MAXSPEED); - Matrix wheelSpeed = reverseAbs.times(motorSpeed); - return wheelSpeed.get(2, 0); - } - - @Override - public Matrix getCurrentSpeed() { - Matrix motorSpeed = getAttribute(ROTATIONSPEED); - Matrix wheelSpeed = reverse.times(motorSpeed); - return toPolar(wheelSpeed.get(0, 0), wheelSpeed.get(1, 0), wheelSpeed.get(2, 0)); - } - - @Override - public double getLinearVelocity() { - return getCurrentSpeed().get(0,0); - } - - @Override - public double getLinearDirection() { - return getCurrentSpeed().get(1,0); - } - - @Override - public double getAngularVelocity() { - return getCurrentSpeed().get(2,0); - } - - - - // Support for move reconstruction for move based pilots - - public void moveStart() { - tachoAtMoveStart = getAttribute(TACHOCOUNT); - } - - @Override - public Move getDisplacement(Move move) { - Matrix currentTacho = getAttribute(TACHOCOUNT); - Matrix delta = currentTacho.minus(tachoAtMoveStart); - - delta = reverse.times(delta); - double distance = Math.sqrt(delta.get(0, 0) * delta.get(0, 0) + delta.get(1, 0) * delta.get(1, 0)); - double rotation = delta.get(2, 0); - if (distance == 0 && rotation == 0 ) - move.setValues(Move.MoveType.STOP, (float) distance, (float) rotation, isMoving()); - else if (Math.abs(rotation) < 1 ) - move.setValues(Move.MoveType.TRAVEL, (float) distance, (float) rotation, isMoving()); - else if (Math.abs(distance) < 1) - move.setValues(Move.MoveType.ROTATE, (float) distance, (float) rotation, isMoving()); - else move.setValues(Move.MoveType.ARC, (float) distance, (float) rotation, isMoving()); - return move; - } - - - /** Provides a modeler object to model a Holonomic motorized wheel on the chassis - * @param motor - * The regulated motor that drives the wheel - * @param diameter - * The diameter of the wheel in a unit of choice. - * @return the modeler - */ - public static HolonomicModeler modelHolonomicWheel(RegulatedMotor motor, double diameter) { - return new HolonomicModeler(motor, diameter); - } - - /** The Modeler class helps to model a wheel. Wheel attributes can be modeled using methods. - *
      - *
    • polarPosition() specifies the location of the wheel
    • - *
    • gearRatio() specifies the gear ratio of the gear train between motor and wheel
    • - *
    • invert() inverts the direction of the motor. Equivalent to a negative gearing
    • - *
    - *

    - * @author Aswin Bouwmeester - * - */ - public static class HolonomicModeler implements Wheel { - protected RegulatedMotor motor; - protected double diameter; - protected double gearRatio = 1; - protected double offset = 0; - protected Pose pose = new Pose(0,0,0); - protected boolean invert = false; - - /** - * Creates a modeler object to model a robot wheel - * - * @param motor - * The regulated motor that drives the wheel - * @param diameter - * The diameter of the wheel (Lego wheels have the diameter printed - * on the side) - */ - public HolonomicModeler(RegulatedMotor motor, double diameter) { - this.motor = motor; - this.diameter = diameter; - } - - /** Specifies the location and orientation of the wheel using polar coordinates

    - * Use this method only when the wheel axis points to the center of the robot. - * @param angle - * Angle between wheel axis and the robots x-axis - * @param radius - * Distance between center of the wheel and center of the robot - * @return the modeler - */ - public HolonomicModeler polarPosition(double angle, double radius) { - pose = new Pose((float)(radius * Math.cos(Math.toRadians(angle))), (float) (radius * Math.sin(Math.toRadians(angle))), (float)(angle) ); - pose.rotateUpdate(90); - return this; - } - - /** Specifies the location and orientation of the wheel using a cartesian coordinates

    - * @param x - * X-position of the center of the wheel in respect to the robots origin - * @param y - * Y-position of the center of the wheel in respect to the robots origin - * @param angle - * Angle between the driving direction of the wheel and the robots x-axis - * @return the modeler - */ - public HolonomicModeler cartesianPosition(double x, double y, double angle) { - pose = new Pose((float)x, (float)y, (float)angle); - return this; - } - - /** - * Defines the gear train between motor and wheel. - * - * @param val - * The ratio between wheel speed and motor speed. A ratio greater than 1 means the wheel turns faster than the motor. - * @return the modeler - */ - public HolonomicModeler gearRatio(double val) { - this.gearRatio = val; - return this; - } - - /** - * Inverts the motor direction - * - * @param val - * @return the modeler - */ - public HolonomicModeler invert(boolean val) { - invert = val; - return this; - } - - public Matrix getFactors() { - // TODO: correct angular component when the wheel axis doesn't go through the origin of the robot - - Matrix factors = new Matrix(1, 3); - factors.set(0, 0, Math.cos(Math.toRadians(pose.getHeading())) * (360 ) / (diameter * Math.PI * gearRatio * (invert ? -1 : 1))); - factors.set(0, 1, Math.sin(Math.toRadians(pose.getHeading())) * (360 ) / (diameter * Math.PI * gearRatio * (invert ? -1 : 1))); - factors.set(0, 2, (( 2 * pose.getLocation().length() ) / (diameter * gearRatio * (invert ? -1 : 1)))); - return factors; - } - - public RegulatedMotor getMotor() { - return motor; - } - - } - - - - - /** Provides a modeler object to model a Holonomic motorized wheel on the chassis - * @param motor - * The regulated motor that drives the wheel - * @param diameter - * The diameter of the wheel in a unit of choice. - * @return the modeler - */ - public static Modeler modelWheel(RegulatedMotor motor, double diameter) { - return new Modeler(motor, diameter); - } - - /** The Modeler class helps to model a wheel. Wheel attributes can be modeled using methods. - *

      - *
    • offset() specifes the location of the wheel along the y-axis
    • - *
    • gearRatio() specifes the gear ratio of the gear train between motor and wheel
    • - *
    • invert() inverts the direction of the motor. Equivalent to a negative gearing
    • - *
    - *

    - * @author Aswin Bouwmeester - * - */ - public static class Modeler implements Wheel { - protected RegulatedMotor motor; - protected double diameter; - protected double gearRatio = 1; - protected double offset = 0; - protected double angle = 0; - protected boolean invert = false; - - /** - * Creates a modeler object to model a robot wheel - * - * @param motor - * The regulated motor that drives the wheel - * @param diameter - * The diameter of the wheel (Lego wheels have the diameter printed - * on the side) - */ - public Modeler(RegulatedMotor motor, double diameter) { - this.motor = motor; - this.diameter = diameter; - } - - /** - * Defines the offset off the wheel - * - * @param val - * The distance between the robots yPose-axis and the center of the - * wheel - * @return the modeler - */ - public Modeler offset(double val) { - this.offset = val; - return this; - } - - /** - * Defines the gear train between motor and wheel. - * - * @param val - * The ratio between wheel speed and motor speed - * @return the modeler - */ - public Modeler gearRatio(double val) { - this.gearRatio = val; - return this; - } - - /** - * Inverts the motor direction - * - * @param val - * @return the modeler - */ - public Modeler invert(boolean val) { - invert = val; - return this; - } - - public Matrix getFactors() { - Matrix factors = new Matrix(1, 3); - factors.set(0, 0, (360 * gearRatio * (invert ? -1 : 1)) / (diameter * Math.PI)); - factors.set(0, 1, 0); - factors.set(0, 2, -((2.0 * offset * gearRatio * (invert ? -1 : 1)) / diameter)); - return factors; - } - - public RegulatedMotor getMotor() { - return motor; - } - - } - - - - @Override - public PoseProvider getPoseProvider() { - if (odometer == null) odometer = new Odometer(); - return odometer; - } - - /** The odometer keeps track of the robot pose based on odometry using the encoders of the regulated motors of the wheels. - * @author Aswin Bouwmeester - * - */ - private class Odometer implements PoseProvider { - Matrix lastTacho; - double xPose, yPose, aPose; - - int time = 64; - - private Odometer() { - lastTacho = getAttribute(TACHOCOUNT); - PoseTracker tracker = new PoseTracker(); - tracker.setDaemon(true); - tracker.start(); - } - - @Override - public Pose getPose() { - return new Pose((float) xPose, (float) yPose, (float) aPose); - } - - @Override - public synchronized void setPose(Pose pose) { - xPose = pose.getX(); - yPose = pose.getY(); - aPose = pose.getHeading(); - } - - private synchronized void updatePose() { - Matrix currentTacho = getAttribute(TACHOCOUNT); - Matrix delta = currentTacho.minus(lastTacho); - - int max = (int) getMax(delta); - - delta = reverse.times(delta); - double sin = Math.sin(Math.toRadians(aPose)); - double cos = Math.cos(Math.toRadians(aPose)); - double x = delta.get(0, 0); - double y = delta.get(1, 0); - - xPose += cos * x - sin * y; - yPose += sin * x + cos * y; - aPose += delta.get(2, 0); - while (aPose < 180) - aPose += 360; - while (aPose > 180) - aPose -= 360; - - // adjust loop speed (between 4 and 64 msec); - if (max > 10) time=time / 2; - if (max < 10) time=time * 2; - time = Math.max(Math.min(time, 64), 4); - lastTacho = currentTacho; - } - - private class PoseTracker extends Thread { - public void run() { - while (true) { - updatePose(); - Delay.msDelay(time); - } - } - } - } - - // Matrix utilities - -/** - * Create a Matrix to store linear and angular components - * - * @param x - * @param y - * @param angular - * @return the modeler - */ -protected Matrix toMatrix(double x, double y, double angular) { - Matrix m = new Matrix(3, 1); - m.set(0, 0, x); - m.set(1, 0, y); - m.set(2, 0, angular); - return m; -} - -protected Matrix toCartesianMatrix ( double radius, double direction, double angular) { - Matrix m = new Matrix(3, 1); - m.set(0, 0, Math.cos(direction) * radius); - m.set(1, 0, Math.sin(direction) * radius); - m.set(2, 0, angular); - return m; -} - -protected Matrix toPolar(double x, double y, double angular) { - Matrix m = new Matrix(3, 1); - m.set(0, 0, Math.sqrt(x * x + y * y)); - m.set(1, 0, Math.toDegrees(Math.atan2(y,x))); - m.set(2, 0, angular); - return m; -} - -/** - * Helper method to get some dynamic attributes from each motor - * - * @param attribute - * @return the mmatrix - */ -protected synchronized Matrix getAttribute(int attribute) { - Matrix x = new Matrix(nWheels+dummyWheels, 1); - master.startSynchronization(); - for (int i = 0; i < nWheels; i++) { - switch (attribute) { - case TACHOCOUNT: - x.set(i, 0, motor[i].getTachoCount()); - break; - case MAXSPEED: - x.set(i, 0, motor[i].getMaxSpeed()); - break; - case ROTATIONSPEED: - x.set(i, 0, motor[i].getRotationSpeed()); - break; - } - } - if (dummyWheels==1) x.set(nWheels, 0, 0); - master.endSynchronization(); - return x; -} - -/** - * Gets the biggest value from a matrix - * - * @param a - */ -protected double getMax(Matrix a) { - double max = Double.NEGATIVE_INFINITY; - for (int m = 0; m < a.getRowDimension(); m++) { - for (int n = 0; n < a.getColumnDimension(); n++) { - if (!Double.isNaN(a.get(m, n))) - max = Math.max(Math.abs(a.get(m, n)), max); - } - } - return max; -} - -/** - * Make a copy of the source matrix, each of its element being the absolute - * value of the elements of the source matrix - * - * @param in - * @return the matrix - */ -protected Matrix copyAbsolute(Matrix in) { - Matrix a = in.copy(); - for (int m = 0; m < a.getRowDimension(); m++) { - for (int n = 0; n < a.getColumnDimension(); n++) { - a.set(m, n, Math.abs(a.get(m, n))); - } - } - return a; -} - - - -} - -/* - * Some remarks regarding the design of the WheeledChassis. - * These originate from a discussion between leJOS developers about the code of this class - * - * The decision to use the same source for both differential and holonomic drive - * systems into one source is deliberate and well thought over. Let me explain - * starting with some facts. 1. Functionality both a holonomic and a - * differential chassis should be the same. 2. Except that the differential - * chassis has a constraint that the the holonomic chassis does not have. A - * differential chassis can only go forward and backward and not sideways. 3. - * This constraint means that you can leave the y-component out of the equation - * when implementing a differential chassis. As the y-component must always be - * zero. - * - * When implementing the two chassis I considered three design options. The - * first was to implement a holonomic chassis on top of (as an extension of) a - * differential chassis. This is impossible when the differential implementation - * ignores the y-component and thus "hard codes" the differential constraint. - * The second option was to implement both chassis independently. This has a - * serious drawback. You need to maintain two sources. The adverse effects of - * this we see in the numerous pilots we now have. Implementing two chassis from - * scratch (including the PoseProvider) would have taken a few hundred lines of - * code extra. The third option was to implement the differential chassis on top - * of the holonomic chassis by adding the constraint of the differential chassis - * in some way. This was easy. I added a dummy (holonomic) wheel to the - * differential chassis. This wheel is oriented sideways and cannot rotate. This - * results in the constraint of y = 0, the differential constraint! With just - * two lines of code I was able to turn a holonomic chassis into a differential - * chassis. To understand the code it helps to always think in terms of a - * holonomic chassis. - * - * Technically it is the inclusion of an y-component that complicates the source - * for a differential chassis. Matrix language is not to blame for that. Matrix - * language does complicates the code but not for this reason. It does - * complicate the code as it requires a different way of thinking. But there is - * a big advantage to linear algebra. It enables you to write an unlimited - * number of similar equations as a single equation or to implement this as a - * single line of code. Linear algebra gives compact code where the logic isn't - * diluted with endless numbers of for-loops. The advantages of linear algebra - * only become apparent when the number of equations (wheels) is more then two. - * So for a differential chassis you can do without and I would have done so if - * I hadn't implemented it as an extension of the holonomic chassis. But for a - * holonomic chassis the advantages are apparent. However now that it is used - * you no longer are constraint to two wheels only, you can have as much wheels - * on your robot as you like. - * - * Then there is the argument of efficiency. Not ignoring the y-component and - * using linear algebra make the code for a differential chassis less efficient. - * This is true. But as long as this is not a bottleneck I see no reason to - * value this argument heavily. It is outweighed by the argument of improved - * maintain ability. I have not jet heard of the performance of the - * WheeledChassis being a bottleneck but only practice will tell. - */ diff --git a/ev3classes/src/main/java/lejos/robotics/chassis/package-info.java b/ev3classes/src/main/java/lejos/robotics/chassis/package-info.java deleted file mode 100644 index d40fd8c..0000000 --- a/ev3classes/src/main/java/lejos/robotics/chassis/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Modeling of wheeled vehicles - */ -package lejos.robotics.chassis; \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/filter/AbstractCalibrationFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/AbstractCalibrationFilter.java deleted file mode 100644 index b204061..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/AbstractCalibrationFilter.java +++ /dev/null @@ -1,209 +0,0 @@ -package lejos.robotics.filter; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; -import java.util.StringTokenizer; - -import lejos.robotics.Calibrate; -import lejos.robotics.SampleProvider; - -public abstract class AbstractCalibrationFilter extends AbstractFilter implements Calibrate{ - public class CalibrationFileException extends RuntimeException { - - - /** - * - */ - private static final long serialVersionUID = -4292630590012678509L; - - public CalibrationFileException(String string) { - super(string); - } - - } - - protected LowPassFilter lowPassFilter = null; - protected float[] min; - protected float[] max; - protected float[] sum; - protected boolean calibrating = false; - - private final static String DIRECTORY = "/home/root/sensorCalibration/"; - private final static String EXT = ".cal"; - private final Properties props = new Properties(); - - protected int numberOfSamplesInCalibration; - private float timeConstant=0; - - - - - public AbstractCalibrationFilter(SampleProvider source) { - super(source); - min=new float[sampleSize]; - max=new float[sampleSize]; - sum=new float[sampleSize]; - } - - - - /** - * Fetches a sample from the sensor and updates array with minimum and maximum values when - * the calibration process is running. - */ - public void fetchSample(float[] dst, int off) { - if (!calibrating) { - source.fetchSample(dst, off); - } - else { - lowPassFilter.fetchSample(dst, off); - numberOfSamplesInCalibration++; - for (int i = 0; i < sampleSize; i++) { - if (min[i] > dst[i + off]) - min[i] = dst[i + off]; - if (max[i] < dst[i + off]) - max[i] = dst[i + off]; - sum[i]+=dst[i+off]; - } - } - } - - /** Sets the time constant for the lowpass filter that is used when calibrating.
    - * A value of zero will effectivly disable the lowpass filter. - * Higher values will remove more noise from the signal and give better results, especially when calibraating for scale. - * The downside of higher timeConstants is that calibrating takes more time. - * @param timeConstant - * between 0 and 1 - */ - public void setTimeConstant(float timeConstant) { - this.timeConstant=timeConstant; - } - - /** - * Starts a calibration proces. Resets collected minimum and maximum values. - * After starting calibration new minimum and maximum values are calculated on - * each fetched sample. From this calibration parameters can be calculated. - */ - - public void startCalibration() { - lowPassFilter = new LowPassFilter(source, timeConstant); - calibrating = true; - numberOfSamplesInCalibration=0; - for (int i = 0; i < sampleSize; i++) { - min[i] = Float.MAX_VALUE; - max[i] = Float.MIN_VALUE; - sum[i]=0; - } - } - - /** - * Halts the process of updating calibration parameters. - */ - public void stopCalibration() { - calibrating = false; - } - - /** - * Halts the process of updating calibration parameters. - */ - public void suspendCalibration() { - calibrating = false; - } - - /** - * Resumes the process of updating calibration parameters after a stop. - */ - public void resumeCalibration() { - calibrating = true; - } - - - - /* - * Methods involved in loading and storing - * calibration parameters on the file system - */ - - private File getFile(String filename) { - return new File(DIRECTORY + filename + EXT); - } - - /** Loads calibration parameters from the file system.
    - * This method raises an exception when the stored calibration parameters do not match the sensor or the calibration class. - * @param filename - * filename of the stored calibration parameters - * @throws FileNotFoundException - */ - protected void load(String filename) throws FileNotFoundException, IOException { - FileInputStream in=null; - props.clear(); - File f = getFile(filename); - in = new FileInputStream(f); - props.load(in); - if (!props.getProperty("type").equals(this.toString())) - throw new CalibrationFileException("Invalid Calibration file. Wrong type for filter."); - if (Integer.parseInt(props.getProperty("sampleSize"))!=sampleSize) - throw new CalibrationFileException("Invalid Calibration file. Sample size does not match."); - if (in != null) - in.close(); - } - - /** Saves the current set of calibration parameters to the file system.

    - * Calibration files are stored in /home/root/sensorCalibration/filename - * @param filename - * Name of the file to store calibration parameters in. - */ - protected void store(String filename) { - try { - new File(DIRECTORY).mkdir(); - File f = getFile(filename); - f.createNewFile(); - FileOutputStream out = new FileOutputStream(f); - props.setProperty("sampleSize", Integer.toString(sampleSize)); - props.setProperty("type", this.toString()); - - props.store(out, "Parameters for sensor calibration"); - out.close(); - } - catch (IOException e) { - e.printStackTrace(); - } - } - - - protected float[] getPropertyArray(String key) { - String raw = props.getProperty(key); - StringTokenizer tokenizer = new StringTokenizer(raw, " "); - int n = tokenizer.countTokens(); - float[] values = new float[n]; - for (int i = 0; i < n; i++) { - values[i] = Float.parseFloat(tokenizer.nextToken()); - } - return values; - } - - protected void setPropertyArray(String key, float[] values) { - StringBuilder builder = new StringBuilder(); - int n = values.length; - for (int i = 0; i < n; i++) { - if (i != 0) - builder.append(" "); - builder.append(values[i]); - } - props.setProperty(key, builder.toString()); - } - - protected void setProperty(String key, float value) { - props.setProperty(key, Float.toString(value)); - } - - protected float getProperty(String key) { - return Float.parseFloat(props.getProperty(key)); - } - - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/AbstractFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/AbstractFilter.java deleted file mode 100644 index 0f0e1e6..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/AbstractFilter.java +++ /dev/null @@ -1,28 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** Base class for Sample filters - * @author Kirk, Aswin - * - */ -public abstract class AbstractFilter implements SampleProvider { - protected final SampleProvider source; - protected int sampleSize; - - public AbstractFilter(SampleProvider source) { - this.source=source; - this.sampleSize=source.sampleSize(); - } - - @Override - public int sampleSize() { - return sampleSize; - } - - @Override - public void fetchSample(float[] sample, int offset) { - source.fetchSample(sample, offset); - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/AzimuthFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/AzimuthFilter.java deleted file mode 100644 index 41b70b5..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/AzimuthFilter.java +++ /dev/null @@ -1,89 +0,0 @@ -package lejos.robotics.filter; -/** - * This class fails to build at the moment (because there is no code. The following dummy class allows it to build - * while we decide what to do wuth it! - * @author andy - * - */ -public class AzimuthFilter -{ - -} -// -//import lejos.robotics.SampleProvider; -// -///** -// * This SampleProvider converts magnetic field strengths from a magnetometer -// * (triaxis compass sensor) into azimuth.
    -// * Azimuth (expressed in radians) is the angle between North and the X-axis of -// * the magnetometer. -// *

    -// * To apply tilt correction specify an accelerometer in the constructor of this -// * class. -// * -// * @author Aswin -// * -// */ -//public class AzimuthFilter extends AbstractFilter { -// float[] m = new float[3]; -// SampleProvider accelerometer = null; -// float[] t; -// Vector3f magneto, accel, west; -// -// /** -// * Constructor for the Azimuth filter without tilt correction. -// *

    -// * -// * @param source -// * SampleProvider that provides magnetic field strength over X, Y and -// * Z -// */ -// public AzimuthFilter(SampleProvider source) { -// super(source); -// sampleSize = 1; -// } -// -// /** -// * Constructor for the Azimuth filter with tilt correction. -// * -// * @param source -// * SampleProvider that provides magnetic field strength over X, Y and -// * Z -// * @param accelerometer -// * ampleProvider that provides acceleration over X, Y and Z -// */ -// public AzimuthFilter(SampleProvider source, SampleProvider accelerometer) { -// this(source); -// this.accelerometer = accelerometer; -// t = new float[3]; -// magneto = new Vector3f(); -// accel = new Vector3f(); -// west = new Vector3f(); -// } -// -// @Override -// public void fetchSample(float[] sample, int offset) { -// double direction; -// source.fetchSample(m, 0); -// if (accelerometer == null) { -// direction = Math.atan2(m[1], m[0]); -// } -// else { -// /** -// * Apply tilt correction. Tilt correction is based on the fact that the -// * cross product of two vectors gives a vector perpendicular to the other -// * two vectors. A vector perpendicular to the gravity vector (down) and -// * the magnetic field vector (north) points east/west. -// */ -// accelerometer.fetchSample(t, 0); -// magneto.set(m); -// accel.set(t); -// west.cross(magneto, accel); -// direction = Math.atan2(west.y, west.x) + .5 * Math.PI; -// } -// if (direction < 0) -// direction += 2 * Math.PI; -// sample[offset] = (float) direction; -// } -// -//} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/ConcatenationFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/ConcatenationFilter.java deleted file mode 100644 index 651bb19..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/ConcatenationFilter.java +++ /dev/null @@ -1,28 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * Simple filter to concatenate two sources - * - * @author Lawrie Griffiths - */ -public class ConcatenationFilter implements SampleProvider { - private SampleProvider source1, source2; - - public ConcatenationFilter(SampleProvider source1, SampleProvider source2) { - this.source1 = source1; - this.source2 = source2; - } - - @Override - public int sampleSize() { - return source1.sampleSize() + source2.sampleSize(); - } - - @Override - public void fetchSample(float[] sample, int offset) { - source1.fetchSample(sample,offset); - source2.fetchSample(sample,source1.sampleSize() + offset); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/Dump.java b/ev3classes/src/main/java/lejos/robotics/filter/Dump.java deleted file mode 100644 index 1e8d80c..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/Dump.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.robotics.filter; - -import lejos.hardware.lcd.LCD; -import lejos.robotics.SampleProvider; - -public class Dump extends AbstractFilter { - String format="%7.3f"; - - public Dump(SampleProvider source) { - super(source); - } - - public Dump(SampleProvider source, String format) { - super(source); - this.format=format; - } - - - public void fetchSample(float[] sample, int offset) { - String f; - super.fetchSample(sample,offset); - LCD.clear(); - for (int i=0;i - * Usefull for example to: - *

  • convert gyro output (degrees/second) to azymuth (Degrees)
  • - *
  • Acceleration to speed
  • - *
  • Speed to position
  • - * @author Aswin - * - */ -public class IntegrationFilter extends AbstractFilter{ - private long lastTime=0; - private final float[] currentValue; - private static final float NANO=(float) Math.pow(10,-9); - - - public IntegrationFilter(SampleProvider source) { - super(source); - currentValue=new float[sampleSize]; - } - - - /** - * Sets the current value of the integrator to the specified value. - * @param value - * The value - */ - public void resetTo(float value) { - for (int i=0;i - * The filter has two modes of operation. In operational mode it corrects - * samples coming from the sensor. In calibration mode the filter calculates - * calibration parameters. - *

    - * - * Operational mode
    - * In operational mode the filter corrects incoming samples for offset and scale - * errors. The correction algorithm can uses calibration parameters for this. - * These calibration parameters can be computed in calibration mode. They can - * also be loaded from the filesystem using the load() method. - *

    - * - * How it works
    - * The correction algorithm uses two calibration parameters, offset and scale.
    - * The offset parameter corrects for offset errors. An offset error results in a - * sample being a fixed amount off the truth: 2 becomes 3, 6 becomes 7. It is - * corrected by subtracting a constant value (1 in this example) from the - * sample, the offset error.
    - * The scale parameter corrects for scale errors. As a result of a scale error a - * sample is always a fixed percentage off the truth: 2 becomes 3, 6 becomes 9. - * It is corrected by dividing the sample with a constant value, the scale - * error, 1.5 in this case.
    - * The combined correction formula is correctedValue = ( rawValue - offsetError - * ) / scaleError. This calibration technique works on all sensors who's output - * is linear to the input.
    - * If no correction parameters are calculated or loaded the filter uses 0 for - * offset correction and 1 for scale correction. - *

    - * - * How to use the filter in operational mode
    - * In operational mode is the default mode. It is always active while the filter - * is not calibrating.
    - *

    - * - * - * - * Calibration mode
    - * In calibration mode the two calibration parameters are calculated. This is - * done by comparing samples to a user specified reference value and/or range. - * Once calibration parameters are calculated they can be used immediately or - * stored to the filesystem for later use using the store() method. - *

    - * - * How it works
    - * The CalibratorFiltersupports both offset and scale calibration. However both - * are optional and can be enabled or disabled. During calibration the filter - * collects minimum and maximum sample values. From this it calculates offset - * (as the average of the minimum and maximum value corrected for the reference - * value) and scale (as the difference between maximum and minimum value scaled - * for range). To minimize the effect of sensor noise or sensor movements during - * calculation sample values are low-passed before they are being used for - * calibration. - *

    - * - * How to use the filter in calibration mode
    - * Calibration is started using the startCalibration method and ended with the - * endCalibration method. During calibration the program that uses the filter - * must fetch samples to collect data for the calibration algorithm. At the end - * the calibration process the calculated calibration settings can be stored - * using the store(filename) method. Calibration can be paused if needed. - *

    - * - * How to tune the calibration process
    - * There are three important parameters to the calibration process that can be - * modified by the user program. - *

      - *
    • - * The reference value. This is the expected output of the sensor. For - * calibrating a (motionless) gyro sensor this will be 0. For calibrating a - * range sensor for example this should be the range to the object the sensor is - * calibrated to. The reference value is used in calculating the offset - * parameter, it is not used in calculating scale. The reference has a default - * value of 0.
    • - *
    • - * The range value. This is the expected range of the sensor output. For - * calibrating an accelerometer this could be 2*9.81 when the output should be - * in m/s^2. The range value is used in calculating the scale parameter, it is - * not used in calculating offset. The range has a default value of 2, meaning - * sample values are normalized to a range of -1 to 1.
    • - *
    • - * The timeConstant value. This is the timeConstant value of a low-pass filter - * that is used in calibration mode. A low pass filter is used during - * calibration to for two reasons. First to overcome the effects of sensor noise - * that could otherwise seriously affect range calculation. Secondly it filters - * out the side effect of user manipulation when turning the sensor as part of - * the calibration process (six way tumbling method). The parameter affects the - * amount of smoothing of the low-pass filter. The higher the value, the - * smoother the samples. Smoother samples are less affected by sensor noise or - * external shocks but take longer to settle. The time constant has a default - * value of 0, meaning no smoothing is done by default.
    • - *
    - * - * @author Aswin Bouwmeester - * - */ -public class LinearCalibrationFilter extends AbstractCalibrationFilter { - public final static int OFFSET_CALIBRATION = 0; - public final static int OFFSET_AND_SCALE_CALIBRATION = 1; - - private float[] lowerBound; - private float[] upperBound; - private float[] offset; - private float[] scale; - private int calibrationType; - - /** - * Construcor - * - * @param source - * SampleProvider - * @param filename - * Filename to load calibration settings from - */ - public LinearCalibrationFilter(SampleProvider source, String filename) { - this(source); - open(filename); - } - - public LinearCalibrationFilter(SampleProvider source) { - super(source); - lowerBound = new float[sampleSize]; - upperBound = new float[sampleSize]; - offset = new float[sampleSize]; - scale = new float[sampleSize]; - - for (int i = 0; i < sampleSize; i++) { - upperBound[i] = 0; - lowerBound[i] = 0; - offset[i] = 0; - scale[i] = 1; - } - } - - public String toString() { - return "LinearCalibrationFilter"; - } - - public void setScaleCalibration(float ulBound) { - for (int i = 0; i < sampleSize; i++) { - lowerBound[i] = -ulBound; - upperBound[i] = ulBound; - } - } - - public void setScaleCalibration(float lBound, float uBound) { - for (int i = 0; i < sampleSize; i++) { - lowerBound[i] = lBound; - upperBound[i] = uBound; - } - } - - public void setScaleCalibration(float[] lBound, float[] uBound) { - for (int i = 0; i < sampleSize; i++) { - lowerBound[i] = lBound[i]; - upperBound[i] = uBound[i]; - } - } - - public void setOffsetCalibration(float offset) { - for (int i = 0; i < sampleSize; i++) { - upperBound[i] = offset; - lowerBound[i] = offset; - } - } - - public void setOffsetCalibration(float[] offset) { - for (int i = 0; i < sampleSize; i++) { - upperBound[i] = offset[i]; - lowerBound[i] = offset[i]; - } - } - - public void setCalibrationType(int calibrationType) { - if (calibrationType < 0 || calibrationType > 1) - throw new IllegalArgumentException(); - this.calibrationType = calibrationType; - } - - public int getCallibrationType() { - return calibrationType; - } - - /** - * Returns an array with the offset correction parameters that are currently - * in use - * - * @return the offset correction array - */ - public float[] getOffsetCorrection() { - float[] ret = new float[sampleSize]; - System.arraycopy(offset, 0, ret, 0, sampleSize); - return ret; - } - - /** - * Returns an array with the scale correction paramaters that are currently in - * use - * - * @return the scale correction array - */ - public float[] getScaleCorrection() { - float[] ret = new float[sampleSize]; - System.arraycopy(scale, 0, ret, 0, sampleSize); - return ret; - } - - /** - * Starts a calibration process. Resets collected minimum and maximum values. - * After starting calibration new minimum and maximum values are calculated on - * each fetched sample. From this updated offset and scale parameters are - * calculated. - */ - @Override - public void startCalibration() { - super.startCalibration(); - reset(); - } - - @Override - public void stopCalibration() { - super.stopCalibration(); -// System.out.println("End calibration using " + numberOfSamplesInCalibration + " samples."); -// for (int i = 0; i < sampleSize; i++) { -// System.out.println("min: " + min[i] + " max: " + max[i] + " sum: " + sum[i] + " lowerbound: " + lowerBound[i] + " upperbound: " + upperBound[i] + " offset: " + offset[i] + "scale: " + scale[i]); -// } - } - - /** - * Stores the calibration parameters, offset and/or scale depending on current - * settings, to a filterProperties file. Stored parameters can later be used - * by the CalibrationFilter. - * - * @param filename - * A name to use for storing calibration parameters - */ - public void save(String filename) { - setPropertyArray("offset", offset); - setPropertyArray("scale", scale); - setProperty("calibrationType", (float) calibrationType); - store(filename); - } - - public void open(String name) { - reset(); - try { - load(name); - offset = getPropertyArray("offset"); - scale = getPropertyArray("scale"); - calibrationType = (int) getProperty("calibrationType"); - } catch (FileNotFoundException e) { - reset(); - e.printStackTrace(); - } catch (CalibrationFileException e) { - System.err.println(e); - reset(); - } - catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - reset(); - } - } - - private void reset() { - for (int i = 0; i < sampleSize; i++) { - offset[i] = 0; - scale[i] = 1; - } - } - - /** - * Fetches a sample from the sensor and updates calibration parameters when - * the calibration process is running. - */ - public void fetchSample(float[] dst, int off) { - super.fetchSample(dst, off); - for (int i = 0; i < sampleSize; i++) { - if (calibrating) { - if (upperBound[i] != lowerBound[i]) - scale[i] = (max[i] - min[i]) / (upperBound[i] - lowerBound[i]); - offset[i] = (max[i] + min[i])/2 - (upperBound[i] + lowerBound[i])/2; - } - else { - dst[i + off] = (dst[i + off] - offset[i]); - if (calibrationType == OFFSET_AND_SCALE_CALIBRATION) - dst[i + off] /= scale[i]; - } - } - - } - - public int getCalibrationType() { - return calibrationType; - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/LowPassFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/LowPassFilter.java deleted file mode 100644 index ec7be4d..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/LowPassFilter.java +++ /dev/null @@ -1,60 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * Provides a low-pass filter for samples
    - * - * @see http://en.wikipedia. - * org/wiki/Low-pass_filter - * @author Aswin - * - */ -public class LowPassFilter extends AbstractFilter { - float[] smoothed; - long lastTime = 0; - float timeConstant; - - /** - * Constructor - * - * @param source - * The source for getting samples - * @param timeConstant - * The cut-off frequency for the filter - */ - public LowPassFilter(SampleProvider source, float timeConstant) { - super(source); - smoothed = new float[sampleSize]; - this.timeConstant = timeConstant; - } - - /** - * Fetches a sample from the source and low-passes it - * - * See http://en.wikipedia.org/wiki/Low-pass_filter - */ - public void fetchSample(float[] dst, int off) { - super.fetchSample(dst, off); - if (lastTime == 0 || timeConstant == 0) { - for (int axis = 0; axis < sampleSize; axis++) { - smoothed[axis] = (dst[off + axis]); - } - } - else { - float dt = (float) ((System.currentTimeMillis() - lastTime) / 1000.0); - float a = dt / (timeConstant + dt); - for (int axis = 0; axis < sampleSize; axis++) { - smoothed[axis] = (1f - a) * smoothed[axis] + a * (dst[off + axis]); - dst[axis + off] = smoothed[axis]; - } - } - lastTime = System.currentTimeMillis(); - } - - public void setTimeConstant(float timeConstant) { - this.timeConstant = timeConstant; - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/MaximumFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/MaximumFilter.java deleted file mode 100644 index 6160ec5..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/MaximumFilter.java +++ /dev/null @@ -1,44 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * This filter returns the maximum values found in the N most recent samples.
    - * The number of samples used is specified in the constructor of the filter. - * - * @author Aswin - * - */ -public class MaximumFilter extends SampleBuffer { - - float[] max; - float[] buf, oldest; - - @Override - public void fetchSample(float[] sample, int off) { - getOldest(oldest, 0); - super.fetchSample(buf, 0); - for (int i = 0; i < sampleSize; i++) { - // if the dropped sample happens to be the biggest sample, then rescan the - // buffer for a smallest value; - if (oldest[i] == max[i] || buf[i] > max[i]) { - max[i] = Float.NEGATIVE_INFINITY; - for (int j = 0; j < actualSize; j++) { - max[i] = Math.max(sampleBuffer[j * sampleSize + i], max[i]); - } - sample[i + off] = max[i]; - } - } - } - - public MaximumFilter(SampleProvider source, int bufferSize) { - super(source, bufferSize); - max = new float[sampleSize]; - for (int i = 0; i < sampleSize; i++) - max[i] = Float.NEGATIVE_INFINITY; - buf = new float[sampleSize]; - oldest = new float[sampleSize]; - - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/MeanFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/MeanFilter.java deleted file mode 100644 index 8189cf3..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/MeanFilter.java +++ /dev/null @@ -1,25 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * This filter returns the mean values found in the N most recent samples.
    - * The number of samples used is specified in the constructor of the filter. - * - * @author Aswin - * - */ -public class MeanFilter extends SumFilter { - - public MeanFilter(SampleProvider source, int length) { - super(source, length); - } - - @Override - public void fetchSample(float[] sample, int off) { - super.fetchSample(sample, off); - for (int i = 0; i < sampleSize; i++) - sample[i + off] /= getActualSize(); - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/MedianFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/MedianFilter.java deleted file mode 100644 index 8d5b2c4..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/MedianFilter.java +++ /dev/null @@ -1,45 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * This filter returns the median value found in the N most recent samples.
    - * The number of samples used is specified in the constructor of the filter. - * - * @author Aswin - * - */ -public class MedianFilter extends SampleBuffer { - - public MedianFilter(SampleProvider source, int bufferSize) { - super(source, bufferSize); - } - - @Override - public void fetchSample(float[] sample, int off) { - float current, smallest, value; - int n, halfWay; - super.fetchSample(sample, off); - for (int i = 0; i < sampleSize; i++) { - current = Float.NEGATIVE_INFINITY; - n = 0; - halfWay = actualSize / 2; - while (n <= halfWay) { - smallest = Float.POSITIVE_INFINITY; - for (int j = 0; j < actualSize; j++) { - value = sampleBuffer[currentPos * sampleSize + i]; - if (value == smallest) - n++; - else if (value > current && value < smallest) - smallest = value; - } - current = smallest; - - n++; - } - sample[i + off] = current; - } - - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/MinimumFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/MinimumFilter.java deleted file mode 100644 index a31a827..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/MinimumFilter.java +++ /dev/null @@ -1,42 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * This filter returns the minimum values found in the N most recent samples.
    - * The number of samples used is specified in the constructor of the filter. - * - * @author Aswin - * - */ -public class MinimumFilter extends SampleBuffer { - - float[] min; - float[] buf, oldest; - - @Override - public void fetchSample(float[] sample, int off) { - getOldest(oldest, 0); - super.fetchSample(buf, 0); - for (int i = 0; i < sampleSize; i++) { - // if the dropped sample happens to be the smallest sample, then rescan - // the buffer for a smallest value; - if (oldest[i] == min[i] || buf[i] < min[i]) { - min[i] = Float.POSITIVE_INFINITY; - for (int j = 0; j < actualSize; j++) { - min[i] = Math.min(sampleBuffer[j * sampleSize + i], min[i]); - } - } - sample[i + off] = min[i]; - } - } - - public MinimumFilter(SampleProvider source, int bufferSize) { - super(source, bufferSize); - min = new float[sampleSize]; - buf = new float[sampleSize]; - oldest = new float[sampleSize]; - - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/ModulusFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/ModulusFilter.java deleted file mode 100644 index f3025bb..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/ModulusFilter.java +++ /dev/null @@ -1,28 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * Simple filter that adjusts the sample to use a specified zero value mod a given value - * - * @author Lawrie Griffiths - * - */ -public class ModulusFilter extends AbstractFilter { - private float[] zeroValue; - float[] sample; - float modulus; - - public ModulusFilter(SampleProvider source, float[] zeroValue, float modulus) { - super(source); - this.zeroValue = zeroValue; - this.modulus = modulus; - } - - public void fetchSample(float sample[], int offset) { - super.fetchSample(sample, offset); - for(int i=0;i - * The offset error is calculated by this class and then substracted from the - * sample to give a corrected sample. The filter works by calculating a running - * mean of a sample. this mean value is compared to the reference value, the - * difference between the two is the offset error. Not all samples are used to - * calculate the running mean. Only those samples that seem to indicate a stable - * (initial) situation are used for calculating the mean. - * - * @author Aswin - * - */ -public class OffsetCorrectionFilter extends AbstractFilter { - float[] offset; - float[] reference; - private float[] mean; - private float[] m2; - private float[] actual; - private Queue[] buffer; - private int bufferSize; - - /** - * Constructor for the offset correction filter using default parameters.
    - * All samples are corrected to a reference value of zero using a window of - * 200 samples for calculating the mean - * - * @param source - * source for sample - */ - public OffsetCorrectionFilter(SampleProvider source) { - this(source, new float[source.sampleSize()]); - } - - /** - * Constructor for the offset correction filter using default window of 200 - * samples.
    - * All samples are corrected to the specified reference values - * - * @param source - * source for sample - * @param reference - * An array with reference values. The array length should match the - * sample size. - */ - public OffsetCorrectionFilter(SampleProvider source, float[] reference) { - this(source, reference, 200); - } - - /** - * Constructor for the offset correction filter.
    - * Constructor - * - * @param source - * Source for sample - * @param reference - * An array with reference values. The array length should match the - * sample size. - * @param bufferSize - * Number of samples to use for calculating offset error - */ - @SuppressWarnings("unchecked") - public OffsetCorrectionFilter(SampleProvider source, float[] reference, int bufferSize) { - super(source); - this.bufferSize = bufferSize; - offset = new float[sampleSize]; - this.reference = reference; - mean = new float[sampleSize]; - m2 = new float[sampleSize]; - actual = new float[sampleSize]; - buffer = new Queue[sampleSize]; - for (int i = 0; i < sampleSize; i++) { - buffer[i] = new LinkedList(); - } - } - - public void fetchSample(float[] sample, int offset) { - super.fetchSample(actual, 0); - updateStatistics(); - for (int i = 0; i < sampleSize; i++) { - sample[i + offset] = actual[i] - mean[i] + reference[i]; - } - } - - private void updateStatistics() { - for (int i = 0; i < sampleSize; i++) { - if (withinLimits(i)) { - if (buffer[i].size() == bufferSize) { - removeSample(i); - } - addSample(i); - } - } - } - - private boolean withinLimits(int i) { - if (actual[i] == Float.NaN) - return false; - if (buffer[i].size() < 15) - return true; - float interval = 2 * this.getStandardDeviation(i); - if (actual[i] < mean[i] - interval) - return false; - if (actual[i] > mean[i] + interval) - return false; - return true; - } - - /** - * Method to maintain the running mean and variance by adding a new value; - * - * @param i - */ - private void addSample(int i) { - float x = actual[i]; - buffer[i].add(new Float(x)); - float delta = x - mean[i]; - mean[i] += delta / buffer[i].size(); - m2[i] += delta * (x - mean[i]); - } - - /** - * Method to maintain the running mean and variance by removing an old value; - * - * @param i - */ - private void removeSample(int i) { - float x = (Float) buffer[i].poll(); - float delta = x - mean[i]; - mean[i] -= delta / buffer[i].size(); - ; - m2[i] -= delta * (x - mean[i]); - } - - - - /** - * Resets the filter - */ - public void reset() { - for (int i=0;i subscribers = new ArrayList(); - - public PublishFilter(SampleProvider source, String name, float frequency) throws IOException { - super(source); - this.name = name; - this.frequency = frequency; - latest = new float[sampleSize]; - ss = new ServerSocket(0); - host = LocalEV3.get().getName(); - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(buf); - // Host name - dos.writeUTF(LocalEV3.get().getName()); - // Port number - dos.writeInt(ss.getLocalPort()); - // Sample name - dos.writeUTF(name); - // Sample size - dos.writeInt(sampleSize); - // Frequency - dos.writeFloat(frequency); - dos.close(); - buf.close(); - publishMessage = buf.toByteArray(); - publishPacket = new DatagramPacket(publishMessage, publishMessage.length, InetAddress.getByName("255.255.255.255"), PUBLISH_PORT); - datagramSocket = new DatagramSocket(); - datagramSocket.setBroadcast(true); - publisher.setDaemon(true); - publisher.start(); - listener.setDaemon(true); - listener.start(); - } - - @Override - public void fetchSample(float[] sample, int offset) { - byte[] sampleMessage; - source.fetchSample(latest, offset); - for(int i=0;i active = new ArrayList(); - - for(Socket s: subscribers) { - try { - OutputStream os = s.getOutputStream(); - os.write(sampleMessage); - os.flush(); - active.add(s); - } catch (IOException e) { - try { - s.close(); - } catch (IOException e1) { - // Ignore - } - } - } - - subscribers = active; - } - } - /* - * Continually send UDP message to publicise this source - */ - private class Publisher extends Thread { - @Override - public void run() { - for(;;) { - try { - datagramSocket.send(publishPacket); - } catch (IOException e) { - e.printStackTrace(); - break; - } - Delay.msDelay(UDP_PERIOD); - } - } - } - - // Listen for new subscribers to the source - private class Listener extends Thread { - @Override - public void run() { - for(;;) { - try { - Socket s = ss.accept(); - synchronized (listener) { - subscribers.add(s); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/PublishedSource.java b/ev3classes/src/main/java/lejos/robotics/filter/PublishedSource.java deleted file mode 100644 index 8e21dc4..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/PublishedSource.java +++ /dev/null @@ -1,161 +0,0 @@ -package lejos.robotics.filter; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import lejos.utility.Delay; - -public class PublishedSource { - protected static final int MAX_PACKET_SIZE = 64; - protected static final int PUBLISH_PORT = 3017; - protected static final int SOCKET_TIMEOUT = 3000; - protected static final int MAX_AGE = 10000; - protected static final int MAX_SAMPLE_MESSAGE_SIZE = 128; - - private static Listener listener = new Listener(); - - static { - listener.setDaemon(true); - listener.start(); - } - - protected String name; - protected int sampleSize; - protected float[] sample; - protected float frequency; - protected String host; - protected int port; - protected long timeStamp; - protected DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); - protected String ipAddress; - protected Socket socket; - protected DataInputStream dis; - - public PublishedSource(String ipAddress, byte[] message) throws IOException { - this.ipAddress = ipAddress; - timeStamp = System.currentTimeMillis(); - ByteArrayInputStream bis = new ByteArrayInputStream(message); - dis = new DataInputStream(bis); - host = dis.readUTF(); - port = dis.readInt(); - name = dis.readUTF(); - sampleSize = dis.readInt(); - frequency = dis.readFloat(); - dis.close(); - bis.close(); - } - - public SubscribedProvider connect() throws IOException { - socket = new Socket(ipAddress, port); - DataInputStream dis = new DataInputStream(socket.getInputStream()); - return new SubscribedProvider(dis, this); - } - - public int sampleSize() { - return sampleSize; - } - - public String getName() { - return name; - } - - public float getFrequency() { - return frequency; - } - - public String getHost() { - return host; - } - - public String getTime() { - Date date = new Date(timeStamp); - return formatter.format(date); - } - - public String getKey() { - return host + ":" + port; - } - - public String getIpAddress() { - return ipAddress; - } - - public int getPort() { - return port; - } - - public long getTimeStamp() { - return timeStamp; - } - - public void close() throws IOException { - if (dis != null) dis.close(); - if (socket != null) socket.close(); - } - - private static Map sources = new HashMap(); - - public static Collection getSources() { - Delay.msDelay(SOCKET_TIMEOUT); // Wait to get new sources - synchronized (sources) { - return sources.values(); - } - } - - private static class Listener extends Thread { - @Override - public void run() { - DatagramSocket socket = null; - DatagramPacket packet = new DatagramPacket (new byte[MAX_PACKET_SIZE], MAX_PACKET_SIZE); - - try { - socket = new DatagramSocket(PUBLISH_PORT); - socket.setSoTimeout(SOCKET_TIMEOUT); - - for(;;) { - try { - socket.receive (packet); - String ip = packet.getAddress().getHostAddress(); - PublishedSource source = new PublishedSource(ip, packet.getData()); - synchronized (sources) { - sources.put(source.getKey(), source); - } - } catch (SocketTimeoutException e) { - // Ignore - } catch (IOException e) { - e.printStackTrace(); - } - - // Remove anything too old from sources - ArrayList removeKeys = new ArrayList(); - - synchronized (sources) { - for(String key: sources.keySet()) { - if (System.currentTimeMillis() - sources.get(key).getTimeStamp() > MAX_AGE) { - removeKeys.add(key); - } - } - for(String key: removeKeys) sources.remove(key); - } - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (socket != null) socket.close(); - } - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/SampleBuffer.java b/ev3classes/src/main/java/lejos/robotics/filter/SampleBuffer.java deleted file mode 100644 index d406e62..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/SampleBuffer.java +++ /dev/null @@ -1,64 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * Provides a buffer to store samples - * - * @author Aswin - * - */ -public abstract class SampleBuffer extends AbstractFilter { - - int bufferSize; - int actualSize = 0; - int currentPos = 0; - float[] sampleBuffer; - - public SampleBuffer(SampleProvider source, int bufferSize) { - super(source); - if (bufferSize < 1) - throw new IllegalArgumentException(); - this.bufferSize = bufferSize; - reset(); - } - - public int getBufferSize() { - return bufferSize; - } - - /** - * Empties the sample buffer - */ - private void reset() { - currentPos = 0; - actualSize = 0; - sampleBuffer = new float[bufferSize * sampleSize]; - } - - int toPos(int i, int index) { - return index * sampleSize + i; - } - - public void fetchSample(float[] sample, int off) { - source.fetchSample(sample, off); - for (int i = 0; i < sampleSize; i++) { - sampleBuffer[currentPos * sampleSize + i] = sample[i + off]; - } - - if (actualSize < bufferSize) - actualSize += 1; - currentPos = (currentPos + 1) % bufferSize; - } - - protected void getOldest(float[] sample, int off) { - for (int i = 0; i < sampleSize; i++) { - sample[i + off] = sampleBuffer[currentPos * sampleSize + i]; - } - } - - protected int getActualSize() { - return actualSize; - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/filter/SampleThread.java b/ev3classes/src/main/java/lejos/robotics/filter/SampleThread.java deleted file mode 100644 index 8b8a58b..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/SampleThread.java +++ /dev/null @@ -1,101 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; -import lejos.utility.Delay; - - -public class SampleThread extends AbstractFilter { - - float[] buffer; - boolean running = true; - private float sampleRate; - int interval; - boolean newSampleAvailable=false; - - /** - * Create an instance and run at sampleRate. - * - * @param source - * A SampleProvider - * @param sampleRate - * The sample rate expressed in Hertz (Samples / second) - */ - public SampleThread(SampleProvider source, float sampleRate) { - super(source); - setSampleRate(sampleRate); - buffer=new float[sampleSize]; - Runner runner = new Runner(); - runner.setDaemon(true); - runner.start(); - } - - - public boolean isNewSampleAvailable() { - return newSampleAvailable; - } - - public synchronized void fetchSample(float[] dst, int off) { - for (int axis=0;axis - * The number of samples used is specified in the constructor of the filter. - * - * @author Aswin - * - */ - -public class SumFilter extends AbstractFilter { - private SampleBuffer worker; - - public SumFilter(SampleProvider source, int length) { - super(source); - // The SumFilter class uses one of two inner classes, depending on the - // length of the buffer - if (length > 8) { - worker = new SmartSum(source, length); - } - else { - worker = new PlainSum(source, length); - } - } - - public void fetchSample(float[] sample, int offset) { - worker.fetchSample(sample, offset); - } - - protected int getActualSize() { - return worker.getActualSize(); - } - - - - /** - * Calculates the sum by adding all the elements in the array every time - * - * @author Aswin - * - */ - private class PlainSum extends SampleBuffer { - float[] latest; - - private PlainSum(SampleProvider source, int length) { - super(source, length); - latest = new float[sampleSize]; - } - - public void fetchSample(float[] sample, int off) { - super.fetchSample(latest, 0); - - for (int i = 0; i < sampleSize; i++) { - float s = 0; - for (int j = 0; j < actualSize; j++) { - s += sampleBuffer[i + j * sampleSize]; - } - sample[i] = s; - } - } - } - - /** - * Calculates the sum by maintaining a sum by substracting old samples and - * adding new samples; - * - * @author Aswin - * - */ - private class SmartSum extends SampleBuffer { - float[] sum; - float[] oldest; - float[] latest; - int[] notRecalculated; - int recalculateIn = 1024; - - private SmartSum(SampleProvider source, int length) { - super(source, length); - sum = new float[sampleSize]; - oldest = new float[sampleSize]; - latest = new float[sampleSize]; - notRecalculated = new int[sampleSize]; - } - - @Override - public void fetchSample(float[] sample, int off) { - /* - * to increase performance this method keeps the sum in memory. If a new - * sample is taken then the oldest available sample is substracted from - * the sum and the new sample is added to it. This prevents the need of - * going to the whole buffer every time. This method does not work well - * with NaN values. Therefore the sum has to be recalculated from the - * buffer when a NaN is dropped from it. There is also the risk of - * building up small numerical errors. Therefor the sum is recalculated - * every so often. - */ - - // get the oldest sample to substract from sum - getOldest(oldest, 0); - // get a fresh sample to add to the sum - super.fetchSample(latest, 0); - // update sum - for (int i = 0; i < sampleSize; i++) { - if (oldest[i] == Float.NaN || notRecalculated[i] > recalculateIn) { - sum[i] = recalculateSum(i); - notRecalculated[i] = 0; - } - else { - sum[i] = sum[i] + latest[i] - oldest[i]; - notRecalculated[i]++; - } - sample[i + off] = sum[i]; - } - } - - private float recalculateSum(int index) { - float s = 0; - for (int i = 0; i < actualSize; i++) { - s += sampleBuffer[index + i * sampleSize]; - } - return s; - } - - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/filter/ZeroFilter.java b/ev3classes/src/main/java/lejos/robotics/filter/ZeroFilter.java deleted file mode 100644 index d42151b..0000000 --- a/ev3classes/src/main/java/lejos/robotics/filter/ZeroFilter.java +++ /dev/null @@ -1,26 +0,0 @@ -package lejos.robotics.filter; - -import lejos.robotics.SampleProvider; - -/** - * Simple filter that adjusts the sample to use a specified zero value - * - * @author Lawrie Griffiths - * - */ -public class ZeroFilter extends AbstractFilter { - private float[] zeroValue; - float[] sample; - - public ZeroFilter(SampleProvider source, float[] zeroValue) { - super(source); - this.zeroValue = zeroValue; - } - - public void fetchSample(float sample[], int offset) { - super.fetchSample(sample, offset); - for(int i=0;i
    WARNING: THIS CLASS IS SHARED BETWEEN THE classes AND pccomms PROJECTS. - * DO NOT EDIT THE VERSION IN pccomms AS IT WILL BE OVERWRITTEN WHEN THE PROJECT IS BUILT. - * - */ -public class Line extends Line2D.Float { - - public Line(float x1, float y1, float x2, float y2) { - super(x1, y1, x2, y2); - } - - /** - * Calculate the point of intersection of two lines. - * - * @param l the second line - * - * @return the point of intersection or null if the lines do not intercept or are coincident - */ - public Point intersectsAt(Line l) { - float x, y, a1, a2, b1, b2; - - if (y2 == y1 && l.y2 == l.y1) return null; // horizontal parallel - if (x2 == x1 && l.x2 == l.x1) return null; // vertical parallel - - // Find the point of intersection of the lines extended to infinity - if (x1 == x2 && l.y1 == l.y2) { // perpendicular - x = x1; - y = l.y1; - } else if (y1 == y2 && l.x1 == l.x2) { // perpendicular - x = l.x1; - y = y1; - } else if (y2 == y1 || l.y2 == l.y1) { // one line is horizontal - a1 = (y2 - y1) / (x2 - x1); - b1 = y1 - a1 * x1; - a2 = (l.y2 - l.y1) / (l.x2 - l.x1); - b2 = l.y1 - a2 * l.x1; - - if (a1 == a2) return null; // parallel - x = (b2 - b1) / (a1 - a2); - y = a1 * x + b1; - } else { - a1 = (x2 - x1) / (y2 - y1); - b1 = x1 - a1 * y1; - a2 = (l.x2 - l.x1) / (l.y2 - l.y1); - b2 = l.x1 - a2 * l.y1; - - if (a1 == a2) return null; // parallel - y = (b2 - b1) / (a1 - a2); - x = a1 * y + b1; - } - - // Check that the point of intersection is within both line segments - if (!between(x,x1,x2)) return null; - if (!between(y,y1,y2)) return null; - if (!between(x,l.x1,l.x2)) return null; - if (!between(y,l.y1,l.y2)) return null; - - return new Point(x, y); - } - - /** - * Returns the minimum distance between two line segments--this line segment and another. If they intersect - * the distance is 0. Lines can be parallel or skewed (non-parallel). - * @param seg The other line segment. - * @return The distance between the two line segments. - */ - public double segDist(Line seg) { - if(this.intersectsLine(seg)) - return 0; - double a = Line2D.ptSegDist(this.getX1(), this.getY1(), this.getX2(), this.getY2(), seg.getX1(), seg.getY1()); - double b = Line2D.ptSegDist(this.getX1(), this.getY1(), this.getX2(), this.getY2(), seg.getX2(), seg.getY2()); - double c = Line2D.ptSegDist(seg.getX1(), seg.getY1(), seg.getX2(), seg.getY2(), this.getX1(), this.getY1()); - double d = Line2D.ptSegDist(seg.getX1(), seg.getY1(), seg.getX2(), seg.getY2(), this.getX2(), this.getY2()); - - double minDist = a; - minDist = (b= x1 && x <= x2) return true; - if (x2 < x1 && x >= x2 && x <= x1) return true; - return false; - } -/** - * Make this line longer by an amount delta at each end. - * Used by DijkstraPathFinder to use the same LineMap as the a RangeScanner - * in MCL navigation. - * @param delta the amount added to each end - */ - public void lengthen( float delta) - { - double angle = Math.atan2(y2 - y1,x2- x1); - x1 = x1 - delta * (float)Math.cos(angle); - y1 = y1 - delta * (float)Math.sin(angle); - x2 = x2 + delta * (float)Math.cos(angle); - y2 = y2 + delta * (float)Math.sin(angle); - - - } - /** - * Return the length of the line - * - * @return the length of the line - */ - public float length() { - return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); - } - - @Override - public Point getP1() { - return new Point(x1,y1); - } - - @Override - public Point getP2() { - return new Point(x2,y2); - } -} - diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Line2D.java b/ev3classes/src/main/java/lejos/robotics/geometry/Line2D.java deleted file mode 100644 index 12100f8..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Line2D.java +++ /dev/null @@ -1,583 +0,0 @@ -package lejos.robotics.geometry; - - - -/** - * An abstract class representing a line in two dimensional space - * - * @author Lawrie Griffiths - * - */ -public abstract class Line2D implements Shape, Cloneable { - /** - * A line in 2D space using float coordinates - */ - public static class Float extends Line2D { - /** - * The x coordinate of the start of the line - */ - public float x1; - /** - * The y coordinate of the start of the line - */ - public float y1; - /** - * The x coordinate of the end of the line - */ - public float x2; - /** - * The y coordinate of the end of the line - */ - public float y2; - - /** - * Creates a zero length line at (0,0) - */ - public Float() {} - - /** - * Create a line from (x1,y1) to (x2,y2) - * - * @param x1 the x coordinate of the start of the line - * @param y1 the y coordinate of the start of the line - * @param x2 the x coordinate of the end of the line - * @param y2 the y coordinate of the end of the line - */ - public Float(float x1, float y1, float x2, float y2) { - setLine(x1, y1, x2, y2); - } - - /** - * Set the float coordinates of the start and end of the line - * - * @param x1 the x coordinate of the start of the line - * @param y1 the y coordinate of the start of the line - * @param x2 the x coordinate of the end of the line - * @param y2 the y coordinate of the end of the line - */ - public void setLine(float x1, float y1, float x2, float y2) { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - } - - /** - * Get the bounds of the line as a Rectangle2D - */ - public Rectangle2D getBounds2D() { - float x, y, w, h; - if (x1 < x2) { - x = x1; - w = x2 - x1; - } else { - x = x2; - w = x1 - x2; - } - if (y1 < y2) { - y = y1; - h = y2 - y1; - } else { - y = y2; - h = y1 - y2; - } - return new Rectangle2D.Float(x, y, w, h); - } - - @Override - public double getX1() { - return x1; - } - - @Override - public double getY1() { - return y1; - } - - @Override - public Point2D getP1() { - return new Point2D.Float(x1, y1); - } - - @Override - public double getX2() { - return x2; - } - - @Override - public double getY2() { - return y2; - } - - @Override - public Point2D getP2() { - return new Point2D.Float(x2, y2); - } - - @Override - public void setLine(double x1, double y1, double x2, double y2) { - this.x1 = (float) x1; - this.y1 = (float) y1; - this.x2 = (float) x2; - this.y2 = (float) y2; - } - } - - /** - * A line in 2D space using float coordinates - */ - public static class Double extends Line2D { - /** - * the x coordinate of the start of the line - */ - public double x1; - - /** - * The y coordinate of the sztart of the line - */ - public double y1; - - /** - * The x coordinate of the end of the line - */ - public double x2; - - /** - * The y coordinate of the start of the line - */ - public double y2; - - /** - * Create a zero length line at (0,0) with double coordinates - */ - public Double() {} - - /** - * Create a line from (x1,y1) to (x2,y2) with double coordinate - * - * @param x1 the x coordinate of the start of the line - * @param y1 the y coordinate of the start of the line - * @param x2 the x coordinate of the end of the line - * @param y2 the y coordinate of the end of the line - */ - public Double(double x1, double y1, double x2, double y2) { - setLine(x1, y1, x2, y2); - } - - @Override - public double getX1() { - return x1; - } - - @Override - public double getY1() { - return y1; - } - - @Override - public Point2D getP1() { - return new Point2D.Double(x1, y1); - } - - @Override - public double getX2() { - return x2; - } - - @Override - public double getY2() { - return y2; - } - - @Override - public Point2D getP2() { - return new Point2D.Double(x2, y2); - } - - @Override - public void setLine(double x1, double y1, double x2, double y2) { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - } - - /** - * Get the bounds of the line as a Rectangle2D - */ - public Rectangle2D getBounds2D() { - double x, y, w, h; - if (x1 < x2) { - x = x1; - w = x2 - x1; - } else { - x = x2; - w = x1 - x2; - } - if (y1 < y2) { - y = y1; - h = y2 - y1; - } else { - y = y2; - h = y1 - y2; - } - return new Rectangle2D.Double(x, y, w, h); - } - } - - /** - * This is an abstract class that cannot be instantiated: use Line2D.Float or Line2D.Double. - */ - protected Line2D() { - } - - /** - * Get the x coordinate of the start of the line - * - * @return the x coordinate as a double - */ - public abstract double getX1(); - - /** - * Get the y coordinate of the start of the line - * - * @return the y coordinate as a double - */ - public abstract double getY1(); - - /** - * Get the start point of the line as a Point2D - * - * @return the Point2D - */ - public abstract Point2D getP1(); - - /** - * Get the x coordinate of the end of the line - * - * @return the x coordinate as a double - */ - public abstract double getX2(); - - /** - * Get the y coordinate of the end of the line - * - * @return the y coordinate as a double - */ - public abstract double getY2(); - - /** - * Get the end point of the line as a Point2D - * - * @return the Point2D - */ - public abstract Point2D getP2(); - - - /** - * Sets the end points of the line using double coordinates. - * - * @param x1 the x coordinate of the start point - * @param y1 the y coordinate of the start point - * @param x2 the x coordinate of the end point - * @param y2 the y coordinate of the end point - */ - public abstract void setLine(double x1, double y1, double x2, double y2); - - /** - * Sets the end points of the line from a given start and end point - * @param p1 the start point - * @param p2 the end point - */ - public void setLine(Point2D p1, Point2D p2) { - setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY()); - } - - /** - * Set the end points of a line to the same as a given line - * - * @param line the given line - */ - public void setLine(Line2D line) { - setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2()); - } - - public boolean contains(double x, double y) { - return false; - } - - public boolean contains(Point2D p) { - return false; - } - - public boolean contains(double x, double y, double w, double h) { - return false; - } - - public boolean contains(Rectangle2D r) { - return false; - } - - public boolean intersects(double x, double y, double w, double h) { - return intersects(new Rectangle2D.Double(x, y, w, h)); - } - - /** - * Test if this line intersects a given line - * - * @param x1 the x coordinate of the start of the given line - * @param y1 the y coordinate of the start of the given line - * @param x2 the x coordinate of the end of the given line - * @param y2 the y coordinate of the end of the given line - * @return true iff the lines intersect - */ - public boolean intersectsLine(double x1, double y1, double x2, double y2) { - return linesIntersect(x1, y1, x2, y2, - getX1(), getY1(), getX2(), getY2()); - } - - /** - * Tests if this line intersects a given line - * - * @param l the given line - * @return true iff the lines intersect - */ - public boolean intersectsLine(Line2D l) { - return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), - getX1(), getY1(), getX2(), getY2()); - } - - /** - * Test if one line intersects another line - * - * @param x1 the x coordinate of the start of the first line - * @param y1 the y coordinate of the start of the first line - * @param x2 the x coordinate of the end of the first line - * @param y2 the y coordinate of the end of the first line - * @param x3 the x coordinate of the start of the second line - * @param y3 the y coordinate of the start of the second line - * @param x4 the x coordinate of the end of the second line - * @param y4 the y coordinate of the end of the second line - * @return true iff the lines intersect - */ - public static boolean linesIntersect( - double x1, double y1, - double x2, double y2, - double x3, double y3, - double x4, double y4) - { - return ((relativeCCW(x1, y1, x2, y2, x3, y3) * - relativeCCW(x1, y1, x2, y2, x4, y4) <= 0) && - (relativeCCW(x3, y3, x4, y4, x1, y1) * - relativeCCW(x3, y3, x4, y4, x2, y2) <= 0)); - } - - public RectangleInt32 getBounds() { - return getBounds2D().getBounds(); - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new RuntimeException(); - } - } - - /** - * Returns an indicator of where the specified point - * lies with respect to the line - * - * @param x1 the x coordinate of the start of the line - * @param y1 the y coordinate of the start of the line - * @param x2 the x coordinate of the end of the line - * @param y2 the y coordinate of the end of the line - * @param px the x coordinate of the specified point - * @param py the y coordinate of the specified point - * @return 0 iff the point is on the line else 1 or -1 depending - * on whether the point in to the left or ahead of the line, or to the right or behind - * the line segment - */ - public static int relativeCCW( - double x1, double y1, - double x2, double y2, - double px, double py) - { - double tx = x2 - x1; - double ty = y2 - y1; - double tpx = px - x1; - double tpy = py - y1; - double ccw = tpx * ty - tpy * tx; - if (ccw == 0) { - ccw = tpx * tx + tpy * ty; - if (ccw > 0) { - tpx -= tx; - tpy -= ty; - ccw = tpx * tx + tpy * ty; - if (ccw < 0) ccw = 0; - } - } - return (ccw < 0) ? -1 : ((ccw > 0) ? 1 : 0); - } - - /** - * Returns an indicator of where the specified point - * lies with respect to the line - * - * @param p the specified point - * @return 0 iff the point is on the line else 1 or -1 depending - * on whether the point in to the left or ahead of the line, or to the right or behind - * the line segment - */ - public int relativeCCW(Point2D p) { - return relativeCCW(getX1(), getY1(), getX2(), getY2(), - p.getX(), p.getY()); - } - - /** - * Returns an indicator of where the specified point - * lies with respect to the line. - * - * @param px the x coordinate of the specified point - * @param py the y coordinate of the specified point - * @return 0 iff the point is on the line else 1 or -1 depending - * on whether the point in to the left or ahead of the line, or to the right or behind - * the line segment - */ - public int relativeCCW(double px, double py) { - return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py); - } - - public boolean intersects(Rectangle2D r) { - return r.intersectsLine(getX1(), getY1(), getX2(), getY2()); - } - - /** - * Measures the square of the shortest distance from the reference point - * to a point on the line segment. If the point is on the segment, the - * result will be 0. - * - * @param x1 the first x coordinate of the segment - * @param y1 the first y coordinate of the segment - * @param x2 the second x coordinate of the segment - * @param y2 the second y coordinate of the segment - * @param px the x coordinate of the point - * @param py the y coordinate of the point - * @return the square of the distance from the point to the segment - */ - public static double ptSegDistSq(double x1, double y1, double x2, double y2, - double px, double py) - { - double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); - - double x, y; - if (pd2 == 0) - { - // Points are coincident. - x = x1; - y = y2; - } - else - { - double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2; - - if (u < 0) - { - // "Off the end" - x = x1; - y = y1; - } - else if (u > 1.0) - { - x = x2; - y = y2; - } - else - { - x = x1 + u * (x2 - x1); - y = y1 + u * (y2 - y1); - } - } - - return (x - px) * (x - px) + (y - py) * (y - py); - } - - /** - * Measures the shortest distance from the reference point to a point on - * the line segment. If the point is on the segment, the result will be 0. - * - * @param x1 the first x coordinate of the segment - * @param y1 the first y coordinate of the segment - * @param x2 the second x coordinate of the segment - * @param y2 the second y coordinate of the segment - * @param px the x coordinate of the point - * @param py the y coordinate of the point - * @return the distance from the point to the segment - */ - public static double ptSegDist(double x1, double y1, double x2, double y2, - double px, double py) - { - return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py)); - } - - /** - * Measures the square of the shortest distance from the reference point - * to a point on this line segment. If the point is on the segment, the - * result will be 0. - * - * @param px the x coordinate of the point - * @param py the y coordinate of the point - * @return the square of the distance from the point to the segment - * @see #ptSegDistSq(double, double, double, double, double, double) - */ - public double ptSegDistSq(double px, double py) - { - return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py); - } - - /** - * Measures the square of the shortest distance from the reference point - * to a point on this line segment. If the point is on the segment, the - * result will be 0. - * - * @param p the point - * @return the square of the distance from the point to the segment - * @throws NullPointerException if p is null - * @see #ptSegDistSq(double, double, double, double, double, double) - */ - public double ptSegDistSq(Point2D p) - { - return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); - } - - /** - * Measures the shortest distance from the reference point to a point on - * this line segment. If the point is on the segment, the result will be 0. - * - * @param px the x coordinate of the point - * @param py the y coordinate of the point - * @return the distance from the point to the segment - * @see #ptSegDist(double, double, double, double, double, double) - */ - public double ptSegDist(double px, double py) - { - return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py); - } - - /** - * Measures the shortest distance from the reference point to a point on - * this line segment. If the point is on the segment, the result will be 0. - * - * @param p the point - * @return the distance from the point to the segment - * @throws NullPointerException if p is null - * @see #ptSegDist(double, double, double, double, double, double) - */ - public double ptSegDist(Point2D p) - { - return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY()); - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Point.java b/ev3classes/src/main/java/lejos/robotics/geometry/Point.java deleted file mode 100644 index 992811c..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Point.java +++ /dev/null @@ -1,287 +0,0 @@ -package lejos.robotics.geometry; - - - -/** - * Point with float co-ordinates for use in navigation. - * This class includes methods allow it to behave as a vector in 2 dimensional - * vector space. It includes the standard vector arithmetic operatins of addition, * subtraction, scalar multiplication, and inner product. - * - * @author Lawrie Griffiths , Roger Glassey - * - */ -public class Point extends Point2D.Float{ - - /** - * returns a Point at location x,y - * @param x coordinate - * @param y coordinate - */ - public Point(float x, float y) { - super(x, y); - } -/** - * Returns a point ad distance 1 from the origin and an angle radans to the x-axis - * @param radians - */ - public Point(float radians) - { - this.x = (float)Math.cos(radians); - this.y = -(float)Math.sin(radians); - } - - -/** - * Returns the direction angle from this point to the Point p - * @param p the Point to determine the angle to - * @return the angle in degrees - */ - public float angleTo(Point p) - { - return (float)Math.toDegrees(Math.atan2(p.getY()-y, p.getX()-x)); - } - - /** - *Translates this point, at location (x, y), by dx along the x axis and - * dy along the y axis so that it now represents the point (x + dx, y + dy). - * @param dx - * @param dy - */ - public void translate(float dx, float dy) - { - x += dx; - y += dy; - } - - /* - * Copy this vector to another vector - */ - public Point copyTo(Point p) - { - p.x = x; - p.y = y; - return p; - } - - /** - * returns a clone of itself - * @return clone of this point - */ - - @Override - public Point clone() - { - return new Point(x, y); - } -/** - * Returns the vector sum of this and other - * @param other the point added to this - * @return vector sum - */ - public Point add(Point other) - { - return new Point(this.x + other.x, this.y + other.y); - } - - /** - * Vector addition; add other to this - * @param other is added to this - * @return this after the addition - */ - public Point addWith(Point other) - { - x += other.x; - y += other.y; - return this; - } -/** - * Makes this a copy of the other point - * @param other - */ - public void moveTo(Point other) - { - x = other.x; - y = other.y; - } -/** - * Vector subtraction - * @param other is subtracted from this - * @return a new point; this point is unchanged - */ - public Point subtract(Point other) - { - return new Point(this.x - other.x, this.y - other.y); - } -/** - * - * Vector subtraction - * @param length of a copy of this - * @return a new vector, obtained b subtracting a scaled version of this point - */ - public Point subtract(float length) - { - return this.subtract(this.getNormalized().multiply(length)); - } -/** - * Scalar multiplication - * @param scale multilies the length of this to give a new length - * @return a new copy of this, with length scaled - */ - public Point multiply(float scale) - { - return new Point(this.x * scale , this.y * scale); - } -/** - * get a copy of this with length 1 - * @return a new vector of unit length - */ - public Point getNormalized() - { - return new Point(this.x / length(), this.y / length()); - } - /** - * same as multiply(-1); - * @return this pointing in the opposite direction - */ - public Point reverse() - { - return this.multiply(-1.0F); - } - - /** - * Finds the orthogonal projection of this point onto the line. - * The projection may lie on an extension of the line - * @param line onto which the projection is made - * @return the projection - */ - - public Point projectOn(Line line) - { - Point origin = line.getP1(); - Point basis = line.getP2().subtract(origin); - Point xx = this.subtract(origin); - float lamda = xx.dotProduct(basis)/basis.dotProduct(basis); - Point projection = basis.multiply(lamda); - projection = projection.add(origin); - return projection; - } - - /** - * returns the angle in radians of this point from the origin. - * The X- axis ie at angle 0. - * @return the angle in radians - */ - - public float angle() - { - return (float)Math.atan2(this.y, this.x); - } -/** - * calculate left orthogonal vector of this - * @return orthogonal vector - */ - public Point leftOrth() - { - return new Point(-y, x); - } - - /** - * calculate the right handed cartesian orthogonal of this poiont - * @return orthogonal vector - */ - public Point rightOrth() - { - return new Point(y, -x); - } - - -/** - * vector subtraction - * @param other is subtracted from this - * @return this point after subtraction - */ - public Point subtractWith(Point other) - { - x -= other.x; - y -= other.y; - return this; - } -/** - * scalar multiplication - * @param scale - * @return scaled this point after multiplication - */ - public Point multiplyBy(float scale) - { - x *= scale; - y *= scale; - return this; - } - - /** - * Returns the length of this vector - * @return the length - */ - public float length() - { - return (float)Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); - } - - /** - * Sets this vector's length to 1 unit while retaining direction - * @return this vector normalized - */ - public Point normalize() - { - float length = length(); - x /= length; - y /= length; - return this; - } - - /** - * Turns this vector into its left-handed cartesian orthagonal - */ - public Point makeLeftOrth() - { - float temp = x; - x = -y; - y = temp; - return this; - } - - /** - * Turns this vector into its right-handed cartesian orthagonal - */ - public Point makeRightOrth() - { - float temp = x; - x = y; - y = -temp; - return this; - } - /** - * Returns the inner dot product. - * @return dot product of this with other - */ - - public float dotProduct(Point other) - { - return this.x * other.x + this.y * other.y; - } - - - /** - * Returns a new point at the specified distance in the direction angle from - * this point. - * @param distance the distance to the new point - * @param angle the angle to the new point - * @return the new point - */ - public Point pointAt(float distance, float angle) - { - float xx = distance*(float)Math.cos(Math.toRadians(angle)) + (float)getX(); - float yy = distance*(float)Math.sin(Math.toRadians(angle)) + (float)getY(); - return new Point(xx,yy); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Point2D.java b/ev3classes/src/main/java/lejos/robotics/geometry/Point2D.java deleted file mode 100644 index c627ec9..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Point2D.java +++ /dev/null @@ -1,260 +0,0 @@ -package lejos.robotics.geometry; - -/** - * An abstract class for a point. - * Subclasses implement float, double and integer coordinates. - * - * @author Lawrie Griffiths - * - */ -public abstract class Point2D implements Cloneable { - /** - * A point with float coordinates. - */ - public static class Float extends Point2D { - /** - * The x coordinate of the point - */ - public float x; - /** - * The y coordinate of the point - */ - public float y; - - /** - * Create a point at (0,0) with float coordinates - */ - public Float() {} - - /** - * Create a point at (x,y) with float coordinates - * - * @param x the x coordinate - * @param y the y coordinate - */ - public Float(float x, float y) { - this.x = x; - this.y = y; - } - - @Override - public double getX() { - return x; - } - - @Override - public double getY() { - return y; - } - - @Override - public void setLocation(double x, double y) { - this.x = (float) x; - this.y = (float) y; - } - - /** - * Set the location of the point - * - * @param x the new x coordinate - * @param y the new y coordinate - */ - public void setLocation(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Represent the Point2SD.Float as a String - */ - @Override - public String toString() { - return "Point2D.Float["+x+", "+y+"]"; - } - } - - /** - * A point with double coordinates. - */ - public static class Double extends Point2D { - /** - * The x coordinate of the point - */ - public double x; - /** - * The y coordinate of the point - */ - public double y; - - /** - * Create a point at (0,0) with double coordinates - */ - public Double() {} - - /** - * Create a point at (x,y) with double coordinates - * - * @param x the x coordinate - * @param y the y coordinate - */ - public Double(double x, double y) { - this.x = x; - this.y = y; - } - - @Override - public double getX() { - return x; - } - - @Override - public double getY() { - return y; - } - - @Override - public void setLocation(double x, double y) { - this.x = x; - this.y = y; - } - - /** - * Represent the Point2D.Double as a String - */ - @Override - public String toString() { - return "Point2D.Double["+x+", "+y+"]"; - } - } - - /** - * This is abstract class that cannot be instantiated. - * Use one of its subclasses. - */ - protected Point2D() { - } - - /** - * Get the x coordinate as a double - * - * @return the x co-ordinate (as a double) - */ - public abstract double getX(); - - /** - * Get the y coordinate as a double - * - * @return the y coordinate (as a double) - */ - public abstract double getY(); - - /** - * Set the location of this Point2D using double coordinates - * - * @param x the new x coordinate - * @param y the new y coordinate - */ - public abstract void setLocation(double x, double y); - - /** - * Set the location of this Point2D to the same as a specified Point2D - * - * @param p the specified Point2D - */ - public void setLocation(Point2D p) { - setLocation(p.getX(), p.getY()); - } - - /** - * Get the square of the distance between two points - * - * @param x1 the x coordinate of the first point - * @param y1 the y coordinate of the first point - * @param x2 the x coordinate of the second point - * @param y2 the y coordinate of the second point - * @return the square of the distance between the points as a double - */ - public static double distanceSq(double x1, double y1, double x2, double y2) { - double tx = x1 - x2; - double ty = y1 - y2; - return (tx * tx + ty * ty); - } - - /** - * Get the the distance between two points - * - * @param x1 the x coordinate of the first point - * @param y1 the y coordinate of the first point - * @param x2 the x coordinate of the second point - * @param y2 the y coordinate of the second point - * @return the distance between the points as a double - */ - public static double distance(double x1, double y1, double x2, double y2) { - return Math.sqrt(distanceSq(x1,y1,x2,y2)); - } - - /** - * Get the square of the distance between two points - * - * @param px the first point - * @param py the second point - * @return the square of the distance between the points as a double - */ - public double distanceSq(double px, double py) { - double tx = px - getX(); - double ty = py - getY(); - return (tx * tx + ty * ty); - } - /** - * Get the square of the distance of this point to a given point - * - * @param pt the given point - * @return the square of the distance to the given point as a double - */ - public double distanceSq(Point2D pt) { - return distanceSq(pt.getX(), pt.getY()); - } - - /** - * Get the distance from this point to a given point as a double - * - * @param px the x coordinate of the given point - * @param py the y coordinate of the given point - * @return the distance to the given point as a double - */ - public double distance(double px, double py) { - return Math.sqrt(distanceSq(px,py)); - } - - /** - * Get the distance from this point to a given point asa double - * - * @param pt the given point - * @return the distance to the given point as a double - */ - public double distance(Point2D pt) { - return Math.sqrt(distanceSq(pt)); - } - - /** - * Test if this point is equal to a given object - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof Point2D) { - Point2D p2d = (Point2D) obj; - return (getX() == p2d.getX()) && (getY() == p2d.getY()); - } - return super.equals(obj); - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new RuntimeException(); - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle.java b/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle.java deleted file mode 100644 index 7757c73..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle.java +++ /dev/null @@ -1,9 +0,0 @@ -package lejos.robotics.geometry; - -public class Rectangle extends Rectangle2D.Float { - - public Rectangle(float x, float y, float w, float h) { - super(x,y,w,h); - } - -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle2D.java b/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle2D.java deleted file mode 100644 index 4d910ea..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Rectangle2D.java +++ /dev/null @@ -1,406 +0,0 @@ -package lejos.robotics.geometry; - -/** - * An abstract class for a Rectangle. - * Subclasses use float, double or integer coordinates. - * - * @author Lawrie Griffiths - * - */ -public abstract class Rectangle2D extends RectangularShape { - /** - * The bitmask that indicates that a point lies to the left of - * this rectangle. - */ - public static final int OUT_LEFT = 1; - - /** - * The bitmask that indicates that a point lies above this rectangle. - */ - public static final int OUT_TOP = 2; - - /** - * The bitmask that indicates that a point lies to the right of this rectangle. - */ - public static final int OUT_RIGHT = 4; - - /** - * The bitmask that indicates that a point lies below this rectangle. - */ - public static final int OUT_BOTTOM = 8; - - /** - * A Rectangle2D with float coordinates. - */ - public static class Float extends Rectangle2D { - /** - * The x coordinate of the top left corner - */ - public float x; - - /** - * The y coordinate of the top right corner - */ - public float y; - - /** - * The width of the rectangle - */ - public float width; - - /** - * The height of the rectangle; - */ - public float height; - - - /** - * Create an empty rectangle at (0,0) - */ - public Float() { - x = y = width = height = 0; - } - - /** - * Create a rectangle with float coordinates - * - * @param x the x coordinate of the top left corner - * @param y the y coordinate of the top left corner - * @param width the width of the rectangle - * @param height the height of the rectangle - */ - public Float(float x, float y, float width, float height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - @Override - public double getX() { - return x; - } - - @Override - public double getY() { - return y; - } - - @Override - public double getWidth() { - - return width; - } - @Override - public double getHeight() { - return height; - } - - @Override - public boolean isEmpty() { - return (width <= 0) || (height <= 0); - } - - /** - * Get the bounds as a Rectangle2D with float coordinates - * @return the bounding rectangle - */ - public Rectangle2D getBounds2D() { - return new Float(x, y, width, height); - } - - /** - * Set the rectangle using float coordinates - * - * @param x the x coordinate of the top left corner - * @param y the y coordinate of the top left corner - * @param w the width - * @param h the height - */ - public void setRect(float x, float y, float w, float h) { - this.x = x; - this.y = y; - this.width = w; - this.height = h; - } - - @Override - public void setRect(Rectangle2D r) { - this.x = (float) r.getX(); - this.y = (float) r.getY(); - this.width = (float) r.getWidth(); - this.height = (float) r.getHeight(); - } - - @Override - public void setRect(double x, double y, double w, double h) { - this.x = (float) x; - this.y = (float) y; - this.width = (float) w; - this.height = (float) h; - } - - @Override - public int outcode(double x, double y) { - int out = 0; - if (this.width <= 0) { - out |= OUT_LEFT | OUT_RIGHT; - } else if (x < this.x) { - out |= OUT_LEFT; - } else if (x > this.x + (double) this.width) { - out |= OUT_RIGHT; - } - if (this.height <= 0) { - out |= OUT_TOP | OUT_BOTTOM; - } else if (y < this.y) { - out |= OUT_TOP; - } else if (y > this.y + (double) this.height) { - out |= OUT_BOTTOM; - } - return out; - } - } - - /** - * A Rectangle2D with double coordinates - */ - public static class Double extends Rectangle2D { - /** - * The x coordinate of the top left corner - */ - public double x; - - /** - * The y coordinate of the top right corner - */ - public double y; - - /** - * The width of the rectangle - */ - public double width; - - /** - * The height of the rectangle; - */ - public double height; - - /** - * Create an empty rectangle at (0,0) - */ - public Double() { - x = y = width = height = 0; - } - - public Double(double x, double y, double width, double height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - @Override - public double getX() { - return x; - } - - @Override - public double getY() { - return y; - } - - @Override - public double getWidth() { - return width; - } - - @Override - public double getHeight() { - return height; - } - - @Override - public boolean isEmpty() { - return (width <= 0) || (height <= 0); - } - - @Override - public void setFrame(double x, double y, double w, double h) { - setRect(x, y, w, h); - } - - public Rectangle2D getBounds2D() { - return new Double(x, y, width, height); - } - - @Override - public void setRect(double x, double y, double w, double h) { - this.x = x; - this.y = y; - this.width = w; - this.height = h; - } - - @Override - public void setRect(Rectangle2D r) { - this.x = r.getX(); - this.y = r.getY(); - this.width = r.getWidth(); - this.height = r.getHeight(); - } - - @Override - public int outcode(double x, double y) { - int out = 0; - if (this.width <= 0) { - out |= OUT_LEFT | OUT_RIGHT; - } else if (x < this.x) { - out |= OUT_LEFT; - } else if (x > this.x + this.width) { - out |= OUT_RIGHT; - } - if (this.height <= 0) { - out |= OUT_TOP | OUT_BOTTOM; - } else if (y < this.y) { - out |= OUT_TOP; - } else if (y > this.y + this.height) { - out |= OUT_BOTTOM; - } - return out; - } - } - - /** - * This is an abstract class which cannot be instantiated: use Rectangle2D.Float, Rectangle2D.Double, or Rectangle. - */ - protected Rectangle2D() { - } - - public boolean contains(double x, double y, double w, double h) { - if (isEmpty() || w <= 0 || h <= 0) return false; - double x0 = getX(); - double y0 = getY(); - return (x >= x0 && y >= y0 && - (x + w) <= x0 + getWidth() && - (y + h) <= y0 + getHeight()); - } - - /** - * Set this rectangle to a rectangle defined by double coordinates - * - * @param x the x coordinate of the top left corner - * @param y the y coordinate of the top right corner - * @param w the width of the rectangle - * @param h the height of the rectangle - */ - public abstract void setRect(double x, double y, double w, double h); - - /** - * Set this Rectangle2D to be the same as a given Rectangle2D - * - * @param r the Rectangle2D - */ - public void setRect(Rectangle2D r) { - setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - @Override - public void setFrame(double x, double y, double w, double h) { - setRect(x, y, w, h); - } - - /** - * Test if this Rectangle2D contains a rectangle defined by double coordinates - */ - public boolean contains(double x, double y) { - double x0 = getX(); - double y0 = getY(); - return (x >= x0 && y >= y0 && - x < x0 + getWidth() && y < y0 + getHeight()); - } - - /** - * Test if this Rectangle2D intersects a rectangle defined by double coordinates - */ - public boolean intersects(double x, double y, double w, double h) { - if (isEmpty() || w <= 0 || h <= 0) return false; - double x0 = getX(); - double y0 = getY(); - return (x + w > x0 && y + h > y0 && - x < x0 + getWidth() && y < y0 + getHeight()); - } - - /** - * Test if this rectangle intersects a given line - * - * @param x1 the x coordinate of the start of the given line - * @param y1 the y coordinate of the start of the given line - * @param x2 the x coordinate of the end of the given line - * @param y2 the y coordinate of the end of the given line - * @return true iff the rectangle intersects the line - */ - public boolean intersectsLine(double x1, double y1, double x2, double y2) { - int out1, out2 = outcode(x2, y2); - if (out2 == 0) return true; - - while ((out1 = outcode(x1, y1)) != 0) { - if ((out1 & out2) != 0) return false; - - if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) { - double x = getX(); - if ((out1 & OUT_RIGHT) != 0) { - x += getWidth(); - } - y1 = y1 + (x - x1) * (y2 - y1) / (x2 - x1); - x1 = x; - } else { - double y = getY(); - if ((out1 & OUT_BOTTOM) != 0) { - y += getHeight(); - } - x1 = x1 + (y - y1) * (x2 - x1) / (y2 - y1); - y1 = y; - } - } - return true; - } - - /** - * Returns a mask value that specifies where a given point lies with respect - * to this rectangle. - * - * @param p the given point - * @return the mask value - */ - public int outcode(Point2D p) { - return outcode(p.getX(), p.getY()); - } - - /** - * Returns a mask value that specifies where a point lies with respect - * to this rectangle. - * - * @param x the x coordinate of the given point - * @param y the y coordinate of the given point - * @return the mask value - */ - public abstract int outcode(double x, double y); - - /** - * Test if the rectangle is equal to a given object - */ - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj instanceof Rectangle2D) { - Rectangle2D r2d = (Rectangle2D) obj; - return ((getX() == r2d.getX()) && - (getY() == r2d.getY()) && - (getWidth() == r2d.getWidth()) && - (getHeight() == r2d.getHeight())); - } - return false; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/RectangleInt32.java b/ev3classes/src/main/java/lejos/robotics/geometry/RectangleInt32.java deleted file mode 100644 index fab15be..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/RectangleInt32.java +++ /dev/null @@ -1,337 +0,0 @@ -package lejos.robotics.geometry; - - - -/** - * A rectangle with integer coordinates. - * - * @author Lawrie Griffiths - * - */ -public class RectangleInt32 extends Rectangle2D { - /** - * The height of the rectangle - */ - public int height; - /** - * The width of the rectangle - */ - public int width; - /** - * The x coordinate of the top left of the rectangle - */ - public int x; - /** - * The y coordinate of the top right of the rectangle - */ - public int y; - - /** - * Creates a rectangle with top left corner at (x,y) and with specified - * width and height. - * @param x the x coordinate of the top left corner - * @param y the y coordinate of the top left corner - * @param width the width of the rectangle - * @param height the height of the rectangle - */ - public RectangleInt32(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - /** - * Creates a rectangle with top left corner at (0,0) and with specified - * width and height. - * @param width the width of the rectangle - * @param height the height of the rectangle - */ - public RectangleInt32(int width, int height) { - this(0,0,width,height); - } - - /** - * Creates an empty rectangle at (0,0). - */ - public RectangleInt32() { - this(0,0); - } - - /** - * Create an empty rectangle at the given point - * @param p trhe point - */ - public RectangleInt32(Point p) { - this((int)p.x, (int)p.y, 0, 0); - } - - /** - * Get the x coordinate as a double - * @return the x coordinate - */ - @Override - public double getX() { - return x; - } - - /** - * Get the y coordinate as a double - * @return the y coordinate - */ - @Override - public double getY() { - return y; - } - - /** - * Get the width as a double - * @return the width - */ - @Override - public double getWidth() { - return width; - } - - /** - * Get the height as a double - * @return the height - */ - @Override - public double getHeight() { - return height; - } - - /** - * Move the rectangle to (x,y) - * @param x the new x coordinate - * @param y the new y coordinate - */ - public void setLocation(int x, int y) { - this.x = x; - this.y = y; - } - - /** - * Set the location of this point to the location of a given point - * - * @param p the given point - */ - public void setLocation(Point p) { - x = (int)p.x; - y = (int)p.y; - } - - /** - * Test if the rectangle is empty - * @return true iff the rectangle is empty - */ - @Override - public boolean isEmpty() { - return (width <= 0 || height <= 0); - } - - /** - * Test if a point given by (x,y) coordinates is within the rectangle - * @param x the x coordinate - * @param y the y coordinate - * @return true iff the point is within the rectangle - */ - public boolean contains(int x, int y) { - return inside(x,y); - } - - /** - * Test if a point is within the rectangle - * @param p the point - * @return true iff the point is within the rectangle - */ - public boolean contains(Point p) { - return contains(p.x, p.y); - } - - /** - * Test if this rectangle contains a specified rectangle - * @param r the specified rectangle - * @return true iff the specified rectangle is contained within this rectangle - */ - public boolean contains(RectangleInt32 r) { - if (isEmpty() || r.isEmpty()) return false; - return contains(r.x, r.y) && contains(r.x + r.width, r.y + r.height); - } - - /** - * Test if this rectangle intersects a specified rectangle - * @param r the given rectangle - * @return true iff this rectangle intersects the given rectangle - */ - public boolean intersects(RectangleInt32 r) { - int tw = width, th = height, rw = r.width, rh = r.height; - if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) return false; - int tx = x, ty = y, rx = r.x, ry = r.y; - rw += rx; - rh += ry; - tw += tx; - th += ty; - return ((rw < rx || rw > tx) && (rh < ry || rh > ty) && - (tw < tx || tw > rx) && (th < ty || th > ry)); - } - - @Override - public RectangleInt32 getBounds() { - return new RectangleInt32(x, y, width, height); - } - - public Rectangle2D getBounds2D() { - return new Rectangle(x, y, width, height); - } - - /** - * Set the bounds of this rectangle - * - * @param x the new x coordinate - * @param y the new y coordinate - * @param width the new width - * @param height the new height - */ - public void setBounds(int x, int y, int width, int height) { - reshape(x, y, width, height); - } - /** - * Set the bounds of this rectangle to the given rectangle - * - * @param r the new rectangle - */ - public void setBounds(RectangleInt32 r) { - setBounds(r.x, r.y, r.width, r.height); - } - - @Override - public void setRect(double x, double y, double width, double height) { - int newx, newy, neww, newh; - - if (x > 2.0 * Integer.MAX_VALUE) { - // Cannot be sensibly represented with integers - newx = Integer.MAX_VALUE; - neww = -1; - } else { - newx = doubleToInt(x, false); - if (width >= 0) width += x-newx; - neww = doubleToInt(width, width >= 0); - } - if (y > 2.0 * Integer.MAX_VALUE) { - // Cannot be sensibly represented with integers - newy = Integer.MAX_VALUE; - newh = -1; - } else { - newy = doubleToInt(y, false); - if (height >= 0) height += y-newy; - newh = doubleToInt(height, height >= 0); - } - reshape(newx, newy, neww, newh); - } - - /** - * Use setBounds. - */ - @Deprecated - public void reshape(int x, int y, int width, int height) { - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } - - private static int doubleToInt(double x, boolean high) { - //Manual clipping not needed: Cast to int also returns MIN/MAX_VALUE for small/large values - //Keep it for performance? - if (x <= Integer.MIN_VALUE) return Integer.MIN_VALUE; - if (x >= Integer.MAX_VALUE) return Integer.MAX_VALUE; - - return (int) (high ? Math.ceil(x) : Math.floor(x)); - } - - /** - * Test if the Rectangle is equal to a given object - * - * @param obj the object - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof Rectangle) { - Rectangle r = (Rectangle)obj; - return ((x == r.x) && (y == r.y) && - (width == r.width) && (height == r.height)); - } else { - return super.equals(obj); - } - } - - /** - * Get the location of the rectangle - * - * @return the (x,y) coordinate of the top left corner - */ - public Point getLocation() { - return new Point(x, y); - } - - /** - * Set the size of the rectangle - * - * @param width the new width - * @param height the new height - */ - public void setSize(int width, int height) { - resize(width, height); - } - - - /** - * Use setSize - */ - @Deprecated - public void resize(int width, int height) { - this.width = width; - this.height = height; - } - - /** - * Returns a String representing this rectangle. - */ - @Override - public String toString() { - return "Rectangle[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; - } - - @Override - public int outcode(double x, double y) { - int out = 0; - if (this.width <= 0) { - out |= OUT_LEFT | OUT_RIGHT; - } else if (x < this.x) { - out |= OUT_LEFT; - } else if (x > this.x + (double) this.width) { - out |= OUT_RIGHT; - } - if (this.height <= 0) { - out |= OUT_TOP | OUT_BOTTOM; - } else if (y < this.y) { - out |= OUT_TOP; - } else if (y > this.y + (double) this.height) { - out |= OUT_BOTTOM; - } - return out; - } - - @Deprecated - public boolean inside(int x, int y) { - int w = this.width; - int h = this.height; - if (w < 0 || h < 0) return false; - if (x < this.x || y < this.y) return false; - w += this.x; - h += this.y; - return ((w < this.x || w > x) && (h < this.y || h > y)); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/RectangularShape.java b/ev3classes/src/main/java/lejos/robotics/geometry/RectangularShape.java deleted file mode 100644 index 3d7f508..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/RectangularShape.java +++ /dev/null @@ -1,184 +0,0 @@ -package lejos.robotics.geometry; - - -/** - * An abstract base class for shapes based on a rectangular frame. - * - * @author Lawrie Griffiths - * - */ -public abstract class RectangularShape implements Shape, Cloneable { - - /** - * Get the x coordinate as a double - * - * @return the x coordinate - */ - public abstract double getX(); - - /** - * Get the y coordinate as a double - * - * @return the y coordinate - */ - public abstract double getY(); - - /** - * Get the width as a double - * - * @return the width - */ - public abstract double getWidth(); - - /** - * Get the height as a double - * - * @return the height - */ - public abstract double getHeight(); - - /** - * Get the minimum value of the x x coordinate - * - * @return the minimum x coordinate - */ - public double getMinX() { - return getX(); - } - - /** - * Get the minimum value of the y coordinate - * - * @return the minimum y coordinate - */ - public double getMinY() { - return getY(); - } - - /** - * Get the maximum value of the x coordinate - * - * @return the maximum y coordinate - */ - public double getMaxX() { - return getX() + getWidth(); - } - - /** - * Get the maximum value of the y coordinate - * - * @return the maximim y coordinate - */ - public double getMaxY() { - return getY() + getHeight(); - } - - /** - * Get the x coordinate of the center of the shape - * - * @return the x coordinate of the center - */ - public double getCenterX() { - return getX() + getWidth() / 2.0; - } - - /** - * Get the y coordinate of the center of the shape - * - * @return the y coordinate of the center - */ - public double getCenterY() { - return getY() + getHeight() / 2.0; - } - - /** - * Get the framing rectangle - * - * @return the framing rectangle - */ - public Rectangle2D getFrame() { - return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight()); - } - - /** - * Test if the rectangular shape is empty - * - * @return true iff the shape is empty - */ - public abstract boolean isEmpty(); - - /** - * Set the frame for the rectangular shape - * - * @param x the x coordinate of the top left corner - * @param y the y coordinate iof the top left corner - * @param w the width - * @param h the height - */ - public abstract void setFrame(double x, double y, double w, double h); - - /** - * Set the frame of the rectangular shape - * - * @param r the framing rectangle - */ - public void setFrame(Rectangle2D r) { - setFrame(r.getX(),r.getY(),r.getWidth(),r.getHeight()); - } - - /** - * Test if the shape contains a Point2D - * @param p the Point2D - * @return true iff this shape contains the Point2D - */ - public boolean contains(Point2D p) { - return contains(p.getX(), p.getY()); - } - - /** - * Test if this shape intersects a given Rectangle2D - * - * @param r the Rectangle2D - * @return true iff this shape intersects the given Rectangle2D - */ - public boolean intersects(Rectangle2D r) { - return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - /** - * Test if this shape contains a given Rectangle2D - * - * @param r the Rectangle2D - * @return true iff this shape contains the given Rectangle2D - */ - public boolean contains(Rectangle2D r) { - return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); - } - - /** - * Get the bounds of this rectangular shape as a Rectangle - * @return the bounds as a Rectangle - */ - public RectangleInt32 getBounds() { - double width = getWidth(); - double height = getHeight(); - if (width < 0 || height < 0) return new RectangleInt32(0, 0, 0, 0); - double x = getX(); - double y = getY(); - double x1 = Math.floor(x); - double y1 = Math.floor(y); - double x2 = Math.ceil(x + width); - double y2 = Math.ceil(y + height); - return new RectangleInt32((int) x1, (int) y1,(int) (x2 - x1), (int) (y2 - y1)); - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new RuntimeException(); - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/Shape.java b/ev3classes/src/main/java/lejos/robotics/geometry/Shape.java deleted file mode 100644 index 5c9052f..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/Shape.java +++ /dev/null @@ -1,81 +0,0 @@ -package lejos.robotics.geometry; - - - -/** - * Shape interface without getPathIterator methods - * - * @author Lawrie Griffiths - * - */ -public interface Shape { - - /** - * Get the bounding Rectangle for the shape - * - * @return the bounding Rectangle - */ - public RectangleInt32 getBounds(); - - /** - * Get the bounding Rectangle2D for the shape - * - * @return the bounding Rectangle2D - */ - public Rectangle2D getBounds2D(); - - /** - * Test if the shape contains the point (x,y) - * - * @param x the x co-ordinate of the point - * @param y the y co-ordinate of the point - * @return true iff the shape contains the point - */ - public boolean contains(double x, double y); - - /** - * Test if the shape contains the Point2D - * - * @param p the Point2D - * @return true iff the shape contains the point - */ - public boolean contains(Point2D p); - - /** - * Test if the shape intersects the rectangle with top left at (x,y), width w and height h. - * - * @param x the x-coordinate of the top left point of the rectangle - * @param y the y-coordinate of the top left point of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @return true iff the shape intersects the rectangle - */ - public boolean intersects(double x, double y, double w, double h); - - /** - * Test if the shape intersects the Rectangle2D r - * - * @param r the Recangle2D - * @return true iff the shape intersects the Rectangle2D - */ - public boolean intersects(Rectangle2D r); - - /** - * Test if the shape contains the rectangle with top left at (x,y), width w and height h. - * - * @param x the x-coordinate of the top left point of the rectangle - * @param y the y-coordinate of the top left point of the rectangle - * @param w the width of the rectangle - * @param h the height of the rectangle - * @return true iff the shape contains the rectangle - */ - public boolean contains(double x, double y, double w, double h); - - /** - * Test if the shape contains the Rectangle2D - * - * @param r the Rectangle2D - * @return true iff the shape contains the Rectangle2D - */ - public boolean contains(Rectangle2D r); -} diff --git a/ev3classes/src/main/java/lejos/robotics/geometry/package-info.java b/ev3classes/src/main/java/lejos/robotics/geometry/package-info.java deleted file mode 100644 index 76b1fb6..0000000 --- a/ev3classes/src/main/java/lejos/robotics/geometry/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Geometric shape support for robotics using float co-ordinates - */ -package lejos.robotics.geometry; diff --git a/ev3classes/src/main/java/lejos/robotics/localization/BeaconLocator.java b/ev3classes/src/main/java/lejos/robotics/localization/BeaconLocator.java deleted file mode 100644 index 5c716ec..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/BeaconLocator.java +++ /dev/null @@ -1,21 +0,0 @@ -package lejos.robotics.localization; - -import java.util.ArrayList; - -/** - * A class that scans a room for beacons and identifies the angles to the beacons. - * - * @author BB - * - */ -public interface BeaconLocator { - - /** - *

    This method performs a scan around the robot. The angle values are always relative to the robot, because it does - * not know which direction it is facing. 0 degrees is the forward direction the robot is facing. Angle increases - * counter-clockwise from 0. So 90 degrees is to the left of the robot, 180 is behind, and 270 is to the right.

    - * - * @return an ArrayList of double values indicating angles to the beacons - */ - public ArrayList locate(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/BeaconPoseProvider.java b/ev3classes/src/main/java/lejos/robotics/localization/BeaconPoseProvider.java deleted file mode 100644 index 54832f0..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/BeaconPoseProvider.java +++ /dev/null @@ -1,334 +0,0 @@ -package lejos.robotics.localization; - -import java.util.ArrayList; - -import lejos.hardware.Sound; -import lejos.robotics.localization.OdometryPoseProvider; -import lejos.robotics.localization.PoseProvider; -import lejos.robotics.navigation.*; - -/** - *

    A PoseProvider that uses beacon triangulation to pinpoint the pose (x, y, heading) of a robot. - * The starting position of the robot must be such that it roughly points in the direction of beacon 2, with beacon 1 to the right - * of the robot, and beacon 3 to the left. This ensures that when it performs the first scan, the beacons are scanned in order - * 1, 2, 3. After the first scan, the robot can move about on its own and will be able to scan them in any order.

    - * - *

    After it does a scan, you will either hear a beep or a buzz. A beep means the calculation worked. A buzz means something went - * wrong with the calculation. This could be the beacon ordering is wrong, or it didn't scan three beacons in, or - * the calculated beacon pose deviated significantly from the estimated odometry pose. In this case, the results are thrown out, - * the odometry pose is used, and it will try another scan after the next move. If you hear a lot of buzzes in a row, it probably - * means it will not recover.

    - * - *

    The class uses an OdometryPoseProvider internally for three reasons: - *

  • 1. To serve as a backup pose provider if the BeaconLocator detects less than 3 beacons, or greater than 3 (meaning - * a false reflection occurred). - *
  • 2. It is time consuming to scan beacons after every move. Instead, this will scan about every 5 moves. In between - * these scans, it uses the OdometryPoseProvider to navigate. - *
  • 3. It is essential to scan the beacons in order. This allows it to determine the identity of each beacon so they are - * properly fed to the equations. The OdometryPoseProvider keeps track of heading so it knows which beacons were scanned.

    - * - *

    The downside of using an OdometryPoseProvider to assist with detecting pose is that the robot needs to be placed - * with an approximate heading prior to first scan. Also, if the robot is moved at any time (lifted and placed with a different - * heading), it probably will no longer be able to identify the beacons and become hopelessly lost. As long as the wheels are - * always on the ground, this should not happen.

    - * - * @author BB - * - */ -public class BeaconPoseProvider implements PoseProvider, MoveListener { - /* - * DEV NOTES: Possible improvements: - * 1. TODO: It is subjective and arbitrary for the programmer to say to it, "Do a beacon scan after every X moves." How do - * I know 5 is the right amount? If I use distance, who is to say 200 cm is the right amount to allow odometry before - * doing another scan? It would be nice if it somehow had a model of potential error building up, and did a scan when - * the potential error got too high. - * TODO: Alt constructor that allows distance to determine when it does scan. Accepts double val. - */ - - // 2. TODO: Ability to not even tell it the coordinates of the beacons. Instead it starts off with the assumption that the - // robot is at 0,0,0. Then it does the particle set with MCL, applies a move, then scan, then weeds out the point cloud. - // Keeps going until it has coordinates of three beacons figured out. Optimally this would be included in BeaconTriangle - // in most or all code. - // Also add methods for saving and loading beacon coordinates to flash memory, then could call this after it has located - // them, and load them in before next trial. - - // 3. TODO: Could also do a sanity check on beacon pose calculation to see if x, y is within say 100 cm of odometry - // pose estimate. If not, then probably a false beacon was scanned and a true beacon was missed (rare) which resulted in it - // thinking it successfully scanned in 3 actual beacons. In this case, it should go with odometry. - - private BeaconTriangle bt; - private BeaconLocator bl; - private OdometryPoseProvider opp; - private int moves = 0; // number of moves it has made since getPose() scanned - private int scanInterval; // perform scan after scanInterval moves have been made - private double distance = 0; // distance traveled since getPose() scanned - private boolean hasScanned = false; // whether it has successfully scanned position yet - - // TODO: Alt constructor that does not attempt to sort the beacons using the odometry (no MoveProvider). - // This constructor will be useful for BeaconLocators that can identify the beacon order/id, such as an NXTCamBeaconLocator. - - /** - *

    Creates a PoseProvider using beacons. The BeaconLocator must be capable of scanning the angles to 3 beacons. - * The BeaconTriangle contains the coordinates of the three beacons. The MoveProvider is simply a Pilot, such as - * DifferentialPilot, which is used to keep track of odometry.

    - * - *

    By default, this class takes a scan every 5 moves of the robot.

    - * - * @param bl a BeaconLocator - * @param bt a BeaconTriangle containing the three beacon coordinates - * @param mp a MoveProvider (Pilot) such as DifferentialPilot. Used for odometry. - */ - public BeaconPoseProvider(BeaconLocator bl, BeaconTriangle bt, MoveProvider mp) { - this(bl, bt, mp, 5); - } - - /** - *

    Creates a PoseProvider using beacons. The BeaconLocator must be capable of scanning the angles to 3 beacons. - * The BeaconTriangle contains the coordinates of the three beacons. The MoveProvider is simply a Pilot, such as - * DifferentialPilot, which is used to keep track of odometry.

    - * - * @param bl a BeaconLocator - * @param bt a BeaconTriangle containing the three beacon coordinates - * @param mp a MoveProvider (Pilot) such as DifferentialPilot. Used for odometry. - * @param scanInterval The number of moves to make between each physical scan. - */ - public BeaconPoseProvider(BeaconLocator bl, BeaconTriangle bt, MoveProvider mp, int scanInterval) { - this.bt = bt; - this.bl = bl; - opp = new OdometryPoseProvider(mp); - mp.addMoveListener(this); - this.scanInterval = scanInterval; - moves = scanInterval; // make sure it starts by doing a scan - } - - /** - * Converts the absolute Cartesian heading into the relative angle values the robot sees when scanning. - * - * @param robotBearing The heading the robot is currently at - * @param cartesianHeading The absolute angle to a beacon from the robot, in Cartesian angle. - * @return relative angle - */ - private static double convertToRelative(double robotBearing, double cartesianHeading) { - - double relativeAngle = 360 - (robotBearing - cartesianHeading); - // normalize so value is between 0 to 360 - while(relativeAngle >= 360) relativeAngle -= 360; - while(relativeAngle < 0) relativeAngle += 360; - return relativeAngle; - } - - public Pose getPose() { - if(moves >= scanInterval) { - ArrayList beaconAngles = bl.locate(); - //System.out.println("BEFORE SORT:"); - //for(int i=0;i odometryAngles = new ArrayList(3); - odometryAngles.add(a1); - odometryAngles.add(a2); - odometryAngles.add(a3); - - //System.out.println("ODOMETRY:"); - //System.out.println("A1 " + a1); - //System.out.println("A2 " + a2); - //System.out.println("A3 " + a3); - //Button.ESCAPE.waitForPressAndRelease(); - - boolean success = sortBeacons(beaconAngles, odometryAngles); - - System.out.println("AFTER SORT:"); - for(int i=0;i 3 then use OdometryPP reading: - return opp.getPose(); - } - - /** - *

    This sorts the beacons into the proper order so that beacons.get(0) returns beacon1, and so on. - * This method assumes beacons will always contain the beacon angles that were scanned in counter-clockwise.

    - * - * Strategy: Pick widest theoretical angle between beacons. There will always be one at least 120 degs. - * Then determine which beacon is clockwise of this angle. - * - * @param beacons an array of three angles. - * @param a1 - * @param a2 - * @param a3 - */ - private static boolean sortBeacons(ArrayList beacons, ArrayList angles) { - // Could take a1, a2, a3 instead. Then do sanity check when done to make sure the difference between a1 and 1, a2 and 2, - // a3 and 3 are all about the same, such as all about 20 degrees from one another--or at least more similar than other - // combos. My second sanity check below does this. - - // 1. Find largest angle between three angles - // Find angles between between different beacon angles and robot - ArrayList midAngles = new ArrayList(); - for(int i=0;i=angles.size()) i2 = 0; - double midAngle = betweenAngles(angles.get(i2), angles.get(i)); - //System.out.println("A" + i2 + "" + i + ": " + midAngle); - midAngles.add(midAngle); - } - - int largestIndex = getLargestIndex(midAngles); - //System.out.println("Largest index " + largestIndex); - double largestAngle = midAngles.get(largestIndex); - //System.out.println("Largest angle " + largestAngle); - - // Figure out which - int aAngleCounterClockwiseIndex = largestIndex + 1; - if(aAngleCounterClockwiseIndex >= 3) aAngleCounterClockwiseIndex = 0; - //System.out.println("aAngleCounterClockwiseIndex " + aAngleCounterClockwiseIndex); - - // Now you want to calculate the theoretical middle angle between largest angle. - double middleAngle = angles.get(largestIndex) + (largestAngle/2); - if(middleAngle >= 360) middleAngle -= 360; - //System.out.println("Middle angle " + middleAngle); - - // 2. Find largest angle between three angles in beacons - //double b12 = betweenAngles(beacons.get(1), beacons.get(0)); - //double b23 = betweenAngles(beacons.get(2), beacons.get(1)); - //double b31 = betweenAngles(beacons.get(0), beacons.get(2)); - //System.out.println("B12 " + b12); - //System.out.println("B23 " + b23); - //System.out.println("B31 " + b31); - - //ArrayList bAngles = new ArrayList(); - //bAngles.add(b12); - //bAngles.add(b23); - //bAngles.add(b31); - //int bLargestIndex = getLargestIndex(bAngles); - //System.out.println("Beacons Largest index " + bLargestIndex); - //System.out.println("Beacons Largest angle " + bAngles.get(bLargestIndex)); - - // Sanity check? If largest angle equals another, then this is a bad situation. Abort and use Odometry. - // What if there are two similar largest angles? Could variability screw this up? If there are two similar ones, - // then what it could do is start to look at which is closest to the expected angle. Too dangerous. - - // Another sanity check? Check if order of both sets of angles goes greatest, least, median or whatever. However, - // this could be dangerous because if two are very similar, a bit of real-world variability could cause it to throw - // out good results. Too dangerous. - - // OK, so now it should pick the next beacon angle counter-clockwise of middleAngle. This will then be designated - // as the same angle index as the theoretical one counter-clockwise. - int beaconAngleCounterClockwiseIndex = 0; // index of beacon to right of middleAngle - double smallestDiff = Double.POSITIVE_INFINITY; - - for(int i=0;i<3;i++) { - double indexedAngle = beacons.get(i); - if(indexedAngle < middleAngle) indexedAngle += 360; // since measuring angle counter clockwise, smaller angles actually add 360 - - double diff = indexedAngle - middleAngle; - if(diff < smallestDiff) { - smallestDiff = diff; - beaconAngleCounterClockwiseIndex = i; - } - } - - //System.out.println("Beacon index counterclockwise of middle angle " + beaconAngleCounterClockwiseIndex); - //System.out.println("Beacon angle counterclockwise of middle angle " + beacons.get(beaconAngleCounterClockwiseIndex)); - - // 3. Now re-sort so that beacons in same order as a1, a2, a3 based on largest angle. - double [] tempAngles = new double[3]; - - int bIndex = beaconAngleCounterClockwiseIndex; - int anglesOrdered = 0; - for(int aIndex = aAngleCounterClockwiseIndex;anglesOrdered<3;aIndex++, bIndex++) { - if(aIndex >=3) aIndex = 0; // loop values to start - if(bIndex >=3) bIndex = 0; // loop values to start - - // NOW WHAT? - - //System.out.println("aIndex " + aIndex); - //System.out.println("bIndex " + bIndex); - //System.out.println("beacons.size() " + beacons.size()); - //System.out.println("angles.size() " + angles.size()); - //System.out.println("tempAngles.length " + tempAngles.length); - // If a31, then 1. If a23 then 3. If a12 then 2. But assigning the actual scanned beacon angle that is after the halfway mark. - tempAngles[aIndex] = beacons.get(bIndex); - anglesOrdered++; - } - - beacons.clear(); - for(int i=0;i angles) { - double largest = 0; - int largestIndex = 0; - for(int i=0;i<3;i++) - if(angles.get(i) > largest) { - largest = angles.get(i); - largestIndex = i; - } - return largestIndex; - } - - /** - * Subtracts two angles in a clockwise direction. - * @param greater The angle counter-clockwise of the other angle - * @param lesser The other angle, clockwise from the other one - * @return - */ - private static double betweenAngles(double greater, double lesser) { - if(greater < lesser) greater += 360; - double ab = greater - lesser; - - return ab; - } - - public void setPose(Pose aPose) { - // TODO When this is called, it sets the current robot location as 0,0 or whatever they set it as. - // All subsequent calculations must add this offset of both coordinates and heading. - // Needs to know current pose to calculate this. - } - - public void moveStarted(Move move, MoveProvider mp) { - - } - - public void moveStopped(Move move, MoveProvider mp) { - // Add distance and/or rotation moved since last reset - distance += move.getDistanceTraveled(); - moves++; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/BeaconTriangle.java b/ev3classes/src/main/java/lejos/robotics/localization/BeaconTriangle.java deleted file mode 100644 index 8c513b5..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/BeaconTriangle.java +++ /dev/null @@ -1,109 +0,0 @@ -package lejos.robotics.localization; - -import lejos.robotics.geometry.Point; -import lejos.robotics.navigation.Pose; - -/** - *

    This class represents three beacons in a triangle. Uses triangulation to calculate the position of the robot.

    - * - *

    Note: The algorithm in calcPose() is taken from "Generalized Geometric Triangulation Algorithm for - * Mobile Robot Absolute Self-Localization" from University of Minho, Portugal, 2003.
    - * http://repositorium.sdum.uminho.pt/bitstream/1822/2023/1/BF-003328.pdf

    - * - *

    Improved version from 2006 (not implemented by this class):
    - * http://repositorium.sdum.uminho.pt/bitstream/1822/6057/1/An Improved Version of the Generalized Geometric Triangulation Algorithm.pdf

    - * - * @author Andy Shaw and BB - * - */ -public class BeaconTriangle { - - // The three beacons in triangle array: - Point beacon1; - Point beacon2; - Point beacon3; - - public BeaconTriangle(Point beacon1, Point beacon2, Point beacon3) { - this.beacon1 = beacon1; - this.beacon2 = beacon2; - this.beacon3 = beacon3; - } - - /** - * Triangulates the pose of a robot given three angles to the three beacons. The angle to a beacon must correspond to - * the proper beacon as given in the BeaconTriangle constructor. For example, the angle a1 in the method calcPose() must - * be the angle to beacon1, as given in the constructor. - * - * @param a1 Angle from robot current heading to beacon 1 (in degrees) - * @param a2 Angle from robot current heading to beacon 2 (in degrees) - * @param a3 Angle from robot current heading to beacon 3 (in degrees) - * @return the pose of the robot (x, y, heading) - */ - public Pose calcPose(double a1, double a2, double a3) - { - // ** NOTE: Line numbers indicate the line from the algorithm in the 2003 paper cited above. ** - // line 1: if less than 3 beacon angles, abort. Unneeded here due to method signature. Will handle in PoseProvider. - - double Y12 = a2 - a1; // line 2 - if (a1 > a2) Y12 = 360 + Y12; // line 3 - double Y31 = a1 - a3; // line 4 - if (a3 > a1) Y31 = 360 + Y31; // line 5 - - // Find distance between beacons: - double L12 = beacon1.distance(beacon2); // line 6 - double L31 = beacon3.distance(beacon1); // line 7 - - // line 8: - double phi = beacon2.angleTo(beacon1); - while (phi <= -180) phi = phi + 360; - while (phi > 180) phi = phi - 360; - - // line 9: - double head12 = beacon1.angleTo(beacon2); - double head13 = beacon1.angleTo(beacon3); - double sigma = head13 - head12; - sigma = 180 - sigma; - while (sigma <= -180) sigma = sigma + 360; - while (sigma > 180) sigma = sigma - 360; - - double gamma = sigma - Y31; // line 10 - - // line 11: - double tau = atan((sin(Y12)*(L12*sin(Y31) - L31*sin(gamma)))/(L31*sin(Y12)*cos(gamma) - L12*cos(Y12)*sin(Y31))); - - if (Y12 < 180 && tau < 0) tau = tau + 180; // line 12 - if (Y12 > 180 && tau > 0) tau = tau - 180; // line 13 - - // TODO: Add calc from line 14 in 2006 paper here to improve algorithm? - - double L1; - if (Math.abs(sin(Y12)) > Math.abs(Y31)) // line 14 - L1 = (L12*sin(tau + Y12))/sin(Y12); - else // Line 15: - L1 = (L31*sin(tau + sigma - Y31))/sin(Y31); - - double xR = beacon1.x - L1*cos(phi+tau); // line 16 - double yR = beacon1.y - L1*sin(phi+tau); // line 17 - double aR = phi + tau - a1; // line 18 - - if (aR <= -180) aR = aR + 360; // line 19 - if (aR > 180) aR = aR - 360; // line 20 - - return new Pose((float)xR, (float)yR, (float)aR); - } - - private static double sin(double d) - { - return Math.sin(Math.toRadians(d)); - } - - private static double cos(double d) - { - return Math.cos(Math.toRadians(d)); - } - - private static double atan(double r) - { - return Math.toDegrees(Math.atan(r)); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/CompassPoseProvider.java b/ev3classes/src/main/java/lejos/robotics/localization/CompassPoseProvider.java deleted file mode 100644 index d8f0cc3..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/CompassPoseProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.robotics.localization; - -import lejos.robotics.DirectionFinder; -import lejos.robotics.navigation.MoveProvider; -import lejos.robotics.navigation.Pose; - -/** - * Pose Provider using a compass (or other direction finder) to provide - * location and heading data. - * - * Note: This is a temporary class to allow access compass data until we have - * a more encompassing solution for data from multiple instrumentation. - * @author BB - * - */ -public class CompassPoseProvider extends OdometryPoseProvider { - - private DirectionFinder compass; - - public CompassPoseProvider(MoveProvider mp, DirectionFinder compass) { - super(mp); - this.compass = compass; - } - - public Pose getPose() { - Pose temp = super.getPose(); - temp.setHeading(compass.getDegreesCartesian()); - return temp; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/MCLParticle.java b/ev3classes/src/main/java/lejos/robotics/localization/MCLParticle.java deleted file mode 100644 index b7f3aba..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/MCLParticle.java +++ /dev/null @@ -1,138 +0,0 @@ -package lejos.robotics.localization; - -import java.util.Random; -import lejos.robotics.*; -import lejos.robotics.geometry.*; -import lejos.robotics.mapping.RangeMap; -import lejos.robotics.navigation.Move; -import lejos.robotics.navigation.Pose; - -/** - * Represents a particle for the particle filtering algorithm. The state of the - * particle is the pose, which represents a possible pose of the robot. - * - * The weight for a particle is set by taking a set of theoretical range readings using a - * map of the environment, and comparing these ranges with those taken by the - * robot. The weight represents the relative probability that the robot has this - * pose. Weights are from 0 to 1. - * - * @author Lawrie Griffiths - * - */ -public class MCLParticle { - private static Random rand = new Random(); - - // Instance variables (kept to minimum to allow maximum number of particles) - private Pose pose; - private float weight = 1; - private static boolean debug = false; - - public static void setDebug(boolean yes) - { - debug = yes; - } - /** - * Create a particle with a specific pose - * - * @param pose the pose - */ - public MCLParticle(Pose pose) { - this.pose = pose; - } - - /** - * Set the weight for this particle - * - * @param weight the weight of this particle - */ - public void setWeight(float weight) { - this.weight = weight; - } - - /** - * Return the weight of this particle - * - * @return the weight - */ - public float getWeight() { - return weight; - } - - /** - * Return the pose of this particle - * - * @return the pose - */ - public Pose getPose() { - return pose; - } - - /** - * Calculate the weight for this particle by comparing its readings with the - * robot's readings - * - * @param rr Robot readings - */ - public void calculateWeight(RangeReadings rr, RangeMap map, float divisor) { - weight = 1; - Pose tempPose = new Pose(); - tempPose.setLocation(pose.getLocation()); - for (int i = 0; i < rr.getNumReadings(); i++) { - if(!map.inside(tempPose.getLocation())) - { - weight = 0; - return; - } - float angle = rr.getAngle(i); - tempPose.setHeading(pose.getHeading() + angle); - float robotReading = rr.getRange(i); - float range = map.range(tempPose); - if (range < 0) { - weight = 0; - if(debug) System.out.println("zero wt"+tempPose); - return; - } - float diff = robotReading - range; - weight *= (float) Math.exp(-(diff * diff) / divisor); - } - } - - /** - * Get a specific reading - * - * @param i the index of the reading - * @return the reading - */ - public float getReading(int i, RangeReadings rr, RangeMap map) { - Pose tempPose = new Pose(); - tempPose.setLocation(pose.getLocation()); - tempPose.setHeading(pose.getHeading() + rr.getAngle(i)); - return map.range(tempPose); - } - - public RangeReadings getReadings(RangeReadings rr, RangeMap map) { - RangeReadings pr = new RangeReadings(rr.getNumReadings()); - - for(int i=0;i= maxIterations) { - if (debug) System.out.println("Lost: count = " + count); - if (count > 0) { // Duplicate the ones we have so far - for (int i = count; i < numParticles; i++) { - particles[i] = new MCLParticle(particles[i % count].getPose()); - particles[i].setWeight(particles[i % count].getWeight()); - } - return false; - } else { // Completely lost - generate a new set of particles - for (int i = 0; i < numParticles; i++) { - particles[i] = generateParticle(); - } - return true; - } - } - float rand = (float) Math.random(); - for (int i = 0; i < numParticles && count < numParticles; i++) { - if (oldParticles[i].getWeight() >= rand) { - Pose p = oldParticles[i].getPose(); - float x = p.getX(); - float y = p.getY(); - float angle = p.getHeading(); - - // Create a new instance of the particle and set its weight - particles[count] = new MCLParticle(new Pose(x, y, angle)); - particles[count++].setWeight(oldParticles[i].getWeight()); - } - } - } - return true; - } - - - - /** - * Calculate the weight for each particle - * @param rr the robot range readings - */ - public boolean calculateWeights(RangeReadings rr, RangeMap map) - { - if(debug) System.out.println(" Calc weights using ranges: "+rr.getRange(0)+" "+rr.getRange(1)+" " - +rr.getRange(2)+" A " - +rr.getAngle(0)+" "+rr.getAngle(1)+" "+rr.getAngle(2)); - if(rr.incomplete()) - { - if(debug) System.out.println("range set incomplete"); - return false; - } - int zeros= 0; - maxWeight = 0f; - for (int i = 0; i < numParticles; i++) - { - particles[i].calculateWeight(rr, map, twoSigmaSquared); - float weight = particles[i].getWeight(); - if (weight > maxWeight) maxWeight = weight; - if(weight == 0 )zeros++; - } - - if(debug) System.out.println("Calc Weights Max wt " +maxWeight+" Zeros "+zeros); - if(maxWeight < .01)return false; - return true; - } - - /** - * Apply a move to each particle - * - * @param move the move to apply - */ - public void applyMove(Move move) { - if (move == null) { - System.out.println("applyMove: null move"); - return; - } - if(debug)System.out.println("particles applyMove "+move.getMoveType()); - maxWeight = 0f; - for (int i = 0; i < numParticles; i++) { - particles[i].applyMove(move, distanceNoiseFactor, angleNoiseFactor); - } - if(debug)System.out.println("particles applyMove Exit"); - } - - /** - * The highest weight of any particle - * - * @return the highest weight - */ - public float getMaxWeight() { - float wt = 0; - for (int i = 0; i < particles.length; i ++ ) wt = Math.max(wt,particles[i].getWeight()); - return wt; - } - - /** - * Get the border where particles should not be generated - * - * @return the border - */ - public float getBorder() { - return border; - } - - /** - * Set border where no particles should be generated - * - * @param border the border - */ - public void setBorder(int border) { - this.border = border; - } - - /** - * Set the standard deviation for the sensor probability model - * @param sigma the standard deviation - */ - public void setSigma(float sigma) { - twoSigmaSquared = 2 * sigma * sigma; - } - - /** - * Set the distance noise factor - * @param factor the distance noise factor - */ - public void setDistanceNoiseFactor(float factor) { - distanceNoiseFactor = factor; - } - - /** - * Set the distance angle factor - * @param factor the distance angle factor - */ - public void setAngleNoiseFactor(float factor) { - angleNoiseFactor = factor; - } - - /** - * Set the maximum iterations for the resample algorithm - * @param max the maximum iterations - */ - public void setMaxIterations(int max) { - maxIterations = max; - } - - /** - * Find the index of the particle closest to a given co-ordinates. - * This is used for diagnostic purposes. - * - * @param x the x-coordinate - * @param y the y-coordinate - * @return the index - */ - public int findClosest(float x, float y) { - float minDistance = BIG_FLOAT; - int index = -1; - for (int i = 0; i < numParticles; i++) { - Pose pose = particles[i].getPose(); - float distance = (float) Math.sqrt((double) ( - (pose.getX() - x) * (pose.getX() - x)) + - ((pose.getY() - y) * (pose.getY() - y))); - if (distance < minDistance) { - minDistance = distance; - index = i; - } - } - return index; - } - - /** - * Serialize the particle set to a data output stream - * - * @param dos the data output stream - * @throws IOException - */ - public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeFloat(maxWeight); - dos.writeInt(numParticles()); - for (int i = 0; i < numParticles(); i++) { - MCLParticle part = getParticle(i); - Pose pose = part.getPose(); - float weight = part.getWeight(); - dos.writeFloat(pose.getX()); - dos.writeFloat(pose.getY()); - dos.writeFloat(pose.getHeading()); - dos.writeFloat(weight); - dos.flush(); - } - } - - public int getIterations() { - return _iterations; - } - /** - * Load serialized particles from a data input stream - * @param dis the data input stream - * @throws IOException - */ - public void loadObject(DataInputStream dis) throws IOException { - maxWeight = dis.readFloat(); - numParticles = dis.readInt(); - MCLParticle[] newParticles = new MCLParticle[numParticles]; - for (int i = 0; i < numParticles; i++) { - float x = dis.readFloat(); - float y = dis.readFloat(); - float angle = dis.readFloat(); - Pose pose = new Pose(x, y, angle); - newParticles[i] = new MCLParticle(pose); - newParticles[i].setWeight(dis.readFloat()); - } - particles = newParticles; - } - - /** - * Find the closest particle to specified coordinates and dump its - * details to a data output stream. - * - * @param rr a dummy set of range readings used to determine the angles - * @param dos the data output stream - * @param x the x-coordinate - * @param y the y-coordinate - * @throws IOException - */ - public void dumpClosest(RangeReadings rr, DataOutputStream dos, float x, float y) throws IOException { - int closest = findClosest(x, y); - MCLParticle p = getParticle(closest); - dos.writeInt(closest); - RangeReadings particleReadings = p.getReadings(rr, map); - particleReadings.dumpObject(dos); - dos.writeFloat(p.getWeight()); - dos.flush(); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/MCLPoseProvider.java b/ev3classes/src/main/java/lejos/robotics/localization/MCLPoseProvider.java deleted file mode 100644 index 7f6c851..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/MCLPoseProvider.java +++ /dev/null @@ -1,567 +0,0 @@ -package lejos.robotics.localization; - -import lejos.robotics.mapping.RangeMap; -import lejos.robotics.navigation.Move; -import lejos.robotics.navigation.MoveListener; -import lejos.robotics.navigation.MoveProvider; -import lejos.robotics.navigation.Pose; -import lejos.robotics.RangeReadings; -import lejos.robotics.RangeScanner; -import lejos.robotics.Transmittable; -import lejos.robotics.geometry.Rectangle2D; -import lejos.robotics.geometry.RectangleInt32; -import lejos.robotics.localization.PoseProvider; - -import java.io.*; -import java.util.ArrayList; - -/** - * Maintains an estimate of the robot pose using sensor data. It uses Monte Carlo - * Localization (See section 8.3 of "Probabilistic Robotics" by Thrun et al.
    - * Uses a {@link MCLParticleSet} to represent the probability distribution of the - * estimated pose. - * It uses a {@link lejos.robotics.navigation.MoveProvider} to supply odometry - * data whenever a movement is completed, - * from which the {@link lejos.robotics.navigation.Pose} of each particle is updated. - * It then uses a {@link lejos.robotics.RangeScanner} to provide - * {@link lejos.robotics.RangeReadings} which are used, together with the - * {@link lejos.robotics.mapping.RangeMap} to calculate the - * probability weight of each {@link MCLParticle} . - * @author Lawrie Griffiths and Roger Glassey - */ - -public class MCLPoseProvider implements PoseProvider, MoveListener, Transmittable -{ - - private MCLParticleSet particles; - private RangeScanner scanner; - private RangeMap map; - private int numParticles; - private float _x, _y, _heading; - private float minX, maxX, minY, maxY; - private double varX, varY, varH; - private boolean updated; - private Updater updater = new Updater(); - private int border; - private boolean debug = false; - private boolean busy = false; - private float BIG_FLOAT = 1000000f; - private RangeReadings readings; - private boolean lost = false; - private boolean incomplete = true; - - /** - * Allocates a new MCLPoseProvider. - * @param mp - the MoveProivder - * @param scanner - the RangeScanner - * @param map - the RangeMap - * @param numParticles number of particles - * @param border of the map - */ - public MCLPoseProvider(MoveProvider mp, RangeScanner scanner, - RangeMap map, int numParticles, int border) - { - this.numParticles = numParticles; - this.border = border; - if (numParticles > 0 && map != null) { - particles = new MCLParticleSet(map, numParticles, border); - } - this.scanner = scanner; - this.map = map; - if (mp != null) mp.addMoveListener(this); - updated = false; - //updater.start(); - } - - /** - * Constructor for use on PC - * @param map the RangeMap - * @param numParticles the numbers of particles - * @param border of the map - */ - public MCLPoseProvider(RangeMap map, int numParticles, int border) { - this.numParticles = numParticles; - this.border = border; - this.map = map; - updated = false; - } - - /** - * Associates a map with the MCLPoseProvider - * (for example a map send from the PC). - * - * @param map the RangeMap - */ - public void setMap(RangeMap map) { - this.map = map; - } - - /** - * Generates an initial particle set in a circular normal distribution, centered - * on aPose. - * @param aPose - center of the cloud - * @param radiusNoise - standard deviation of the radius of the cloud - * @param headingNoise - standard deviation of the heading; - */ - public void setInitialPose(Pose aPose, float radiusNoise, float headingNoise) - { - _x = aPose.getX(); - _y = aPose.getY(); - _heading = aPose.getHeading(); - particles = new MCLParticleSet(map, numParticles, aPose, radiusNoise, headingNoise); - } - - /** - * Generates an initial particle set using the range readings. The particles - * have a significant probability weight given the readings. - * @param readings - * @param sigma range reading noise standard deviation. - */ - public void setInitialPose(RangeReadings readings,float sigma) - { - if(debug) System.out.println("MCLPP set Initial pose called "); - float minWeight = 0.3f; - particles = new MCLParticleSet(map, numParticles,border,readings, 2*sigma*sigma,minWeight ); - updated = true; - } - - /** - * Set debugging on or off - * @param on true = on, false = off - */ - public void setDebug(boolean on) { - debug = on; - } - - /** - * set the initial pose cloud with radius noise 1 and heading noise 1 - */ - public void setPose(Pose aPose) - { - setInitialPose(aPose, 1, 1); - updated = true; - } - - /** - * Returns the particle set - * @return the particle set - */ - public MCLParticleSet getParticles() - { - synchronized (particles) { - return particles; - } - } - - /** - * Get the current range readings - * - * @return the RangeReadings object - */ - public RangeReadings getReadings() { - return readings; - } - - /** - * Associate a particle set with the MCLPoseProvider - * (e.g. particles sent from the PC) - * - * @param particles the particle set - */ - public void setParticles(MCLParticleSet particles) { - this.particles = particles; - numParticles = particles.numParticles(); - } - - /** - * Generate a new particle set, uniformly distributed within the map, and - * uniformly distributed heading. - */ - public void generateParticles() - { - particles = new MCLParticleSet(map, numParticles, border); - } - - /** - Required by MoveListener interface; does nothing - */ - public void moveStarted(Move event, MoveProvider mp) { updated = false;} - - /** - * Required by MoveListener interface. The pose of each particle is updated - * using the odometry data of the Move object. - * @param event the move just completed - * @param mp the MoveProvider - */ - public void moveStopped(Move event, MoveProvider mp) - { - if (debug) System.out.println("MCL move stopped"); - //updated = false; - //updater.moveStopped(event); - particles.applyMove(event); - } - - /** - * - * Calls range scanner to get range readings, calculates the probabilities - * of each particle from the range readings and the map and calls resample(() - * - * @return true if update was successful - */ - public boolean update() - { - // if(updated) return true; - if(debug)System.out.println("MCLPP update called "); - updated = false; - if (scanner == null) - { - return false; - } - readings = scanner.getRangeValues(); - if (debug) readings.printReadings(); - incomplete = readings.incomplete(); - // if(debug) System.out.println("mcl Update: range readings " + readings.getNumReadings()); - if (incomplete ) - { - return false; - } - return update(readings); - } - - /** - * Calculates particle weights from readings, then resamples the particle set; - * @param readings - * @return true if update was successful. - */ - @SuppressWarnings("hiding") - public boolean update(RangeReadings readings) - { - if(debug)System.out.println("MCLPP update readings called "); - updated = false; - incomplete = readings.incomplete(); - - if (incomplete) { - return false; - } - - if(debug)System.out.println("update readings incomplete "+incomplete); - boolean goodPose = false; - - goodPose = particles.calculateWeights(readings, map); - if (debug) System.out.println(" max Weight " + particles.getMaxWeight()+ - " Good pose "+goodPose); - - if (!goodPose) { - if (debug) System.out.println("Sensor data improbable from this pose "); - return false; - } - - goodPose = particles.resample(); - updated = goodPose; - - if (debug) { - if (goodPose) System.out.println("Resample done"); - else System.out.println("Resample failed"); - } - - return goodPose; - } - - /** - * Returns update success flag - * @return true if update is successful - */ - public boolean isUpdated() {return updated;} - - /** - * returns lost status - all particles have very low probability weights - * @return true if robot is lost - */ - public boolean isLost() { return lost; } - - /** - * returns range scanner failure status - * @return true if range readings are incomplete - */ - public boolean incompleteRanges() { return incomplete;} - - /** - * Returns the difference between max X and min X - * @return the difference between min and max X - */ - public float getXRange() - { - return getMaxX() - getMinX(); - } - - /** - * Return difference between max Y and min Y - * @return difference between max and min Y - */ - public float getYRange() - { - return getMaxY() - getMinY(); - } - - /** - * Returns the best best estimate of the current pose; - * @return the estimated pose - */ - public Pose getPose() - { - if(debug) System.out.println("Mcl call update; updated? "+updated - +" busy "+busy); - if (!updated) - { - while(busy){ - if(debug) System.out.println("MCL Busy"); - Thread.yield(); - } - if(debug) System.out.println("Mcl call update; updated? "+updated); - if(!updated)update(); - } - estimatePose(); - return new Pose(_x, _y, _heading); - } - - public Pose getEstimatedPose() { - return new Pose(_x, _y, _heading); - } - - /** - * Estimate pose from weighted average of the particles - * Calculate statistics - */ - public void estimatePose() - { - float totalWeights = 0; - float estimatedX = 0; - float estimatedY = 0; - float estimatedAngle = 0; - varX = 0; - varY = 0; - varH = 0; - minX = BIG_FLOAT; - minY = BIG_FLOAT; - maxX = -BIG_FLOAT; - maxY = -BIG_FLOAT; - - for (int i = 0; i < numParticles; i++) - { - Pose p = particles.getParticle(i).getPose(); - float x = p.getX(); - float y = p.getY(); - //float weight = particles.getParticle(i).getWeight(); - float weight = 1; // weight is historic at this point, as resample has been done - estimatedX += (x * weight); - varX += (x * x * weight); - estimatedY += (y * weight); - varY += (y * y * weight); - float head = p.getHeading(); - estimatedAngle += (head * weight); - varH += (head * head * weight); - totalWeights += weight; - - if (x < minX) minX = x; - - if (x > maxX)maxX = x; - if (y < minY)minY = y; - if (y > maxY) maxY = y; - } - - estimatedX /= totalWeights; - varX /= totalWeights; - varX -= (estimatedX * estimatedX); - estimatedY /= totalWeights; - varY /= totalWeights; - varY -= (estimatedY * estimatedY); - estimatedAngle /= totalWeights; - varH /= totalWeights; - varH -= (estimatedAngle * estimatedAngle); - - // Normalize angle - while (estimatedAngle > 180) estimatedAngle -= 360; - while (estimatedAngle < -180) estimatedAngle += 360; - - _x = estimatedX; - _y = estimatedY; - _heading = estimatedAngle; - } - - /** - * Returns most recent range readings - * @return the range readings - */ - public RangeReadings getRangeReadings() - { - return readings; - } - /** - * Returns the minimum rectangle enclosing all the particles - * @return rectangle : the minimum rectangle enclosing all the particles - */ - public Rectangle2D getErrorRect() - { - return new RectangleInt32((int) minX, (int) minY, - (int) (maxX - minX), (int) (maxY - minY)); - } - - /** - * Returns the maximum value of X in the particle set - * @return max X - */ - public float getMaxX() - { - return maxX; - } - - /** - * Returns the minimum value of X in the particle set; - * @return minimum X - */ - public float getMinX() - { - return minX; - } - - /** - * Returns the maximum value of Y in the particle set; - * @return max y - */ - public float getMaxY() - { - return maxY; - } - - /** - * Returns the minimum value of Y in the particle set; - * @return minimum Y - */ - public float getMinY() - { - return minY; - } - - /** - * Returns the standard deviation of the X values in the particle set; - * @return sigma X - */ - public float getSigmaX() - { - return (float) Math.sqrt(varX); - } - - /** - * Returns the standard deviation of the Y values in the particle set; - * @return sigma Y - */ - public float getSigmaY() - { - return (float) Math.sqrt(varY); - } - - /** - * Returns the standard deviation of the heading values in the particle set; - * @return sigma heading - */ - public float getSigmaHeading() - { - return (float) Math.sqrt(varH); - } - - /** - * Returns the range scanner - * @return the range scanner - */ - public RangeScanner getScanner() - { - return scanner; - } - - /** - * Dump the serialized estimate of pose to a data output stream - * @param dos the data output stream - * @throws IOException - */ - public void dumpObject(DataOutputStream dos) throws IOException - { - dos.writeFloat(_x); - dos.writeFloat(_y); - dos.writeFloat(_heading); - dos.writeFloat(minX); - dos.writeFloat(maxX); - dos.writeFloat(minY); - dos.writeFloat(maxY); - dos.writeFloat((float) varX); - dos.writeFloat((float) varY); - dos.writeFloat((float) varH); - dos.flush(); - } - - /** - * Load serialized estimated pose from a data input stream - * @param dis the data input stream - * @throws IOException - */ - public void loadObject(DataInputStream dis) throws IOException - { - _x = dis.readFloat(); - _y = dis.readFloat(); - _heading = dis.readFloat(); - minX = dis.readFloat(); - maxX = dis.readFloat(); - minY = dis.readFloat(); - maxY = dis.readFloat(); - varX = dis.readFloat(); - varY = dis.readFloat(); - varH = dis.readFloat(); - if (debug) System.out.println("Estimate = " + minX + " , " + maxX + " , " + minY + " , " + maxY); - } - - /** - * returns true if particle weights are being updated. The robot should not move - * while this is happening otherwise the prediction from odometry data may - * introduce errors into the updating. - * @return true if weight update is in progress. - */ - public boolean isBusy() { return busy;} - - /** - * Predicts particle pose from odometry data. - */ - class Updater extends Thread - { - boolean keepGoing = true; - ArrayList events = new ArrayList(); - - public void moveStopped(Move theEvent) - { - events.add(theEvent); - } - - @Override - public void run() - { - while (keepGoing) - { - while(!events.isEmpty()) - { - Move event = events.get(0); - if (event == null) System.out.println("MCLPoseProvider: null event"); - else { - if(debug) System.out.println("Updater move stop "+event.getMoveType()); - busy = true; - - synchronized (particles) { - particles.applyMove(event); - } - if(debug) System.out.println("applied move "); - } - events.remove(0); - } - busy = false; - Thread.yield(); - } - } // end run() - }// end class Updater -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/OdometryPoseProvider.java b/ev3classes/src/main/java/lejos/robotics/localization/OdometryPoseProvider.java deleted file mode 100644 index c6340c3..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/OdometryPoseProvider.java +++ /dev/null @@ -1,148 +0,0 @@ -package lejos.robotics.localization; - -import lejos.robotics.SampleProvider; -import lejos.robotics.geometry.Point; -import lejos.robotics.navigation.Move; -import lejos.robotics.navigation.MoveListener; -import lejos.robotics.navigation.MoveProvider; -import lejos.robotics.navigation.Pose; - -/** - *

    A PoseProvider keeps track of the robot {@link lejos.robotics.navigation.Pose}. - * It does this using odometry (dead reckoning) - * data contained in a {@link lejos.robotics.navigation.Move}, which is supplied by a {@link - *lejos.robotics.navigation.MoveProvider}. When the PoseProivder is constructed, it registers - * as listener with its MoveProvider, - */ - -public class OdometryPoseProvider implements PoseProvider, MoveListener, SampleProvider -{ - - private float x = 0, y = 0, heading = 0; - private float angle0, distance0; - MoveProvider mp; - boolean current = true; - - /** - *Allocates a new OdometryPoseProivder and registers it with the MovePovider as a listener. - */ - public OdometryPoseProvider(MoveProvider mp) - { - mp.addMoveListener(this); - } - - /** - * returns a new pose that represents the current location and heading of the robot. - * If called while the robot is moving, the PoseProvider will get updated odometry - * data from its MoveProvider - * @return pose - */ - public synchronized Pose getPose() - { - if (!current ) - { - updatePose(mp.getMovement()); - } - return new Pose(x, y, heading); - } - - /** - * called by a MoveProvider when movement starts - * @param move - the event that just started - * @param mp the MoveProvider that called this method - */ - public synchronized void moveStarted(Move move, MoveProvider mp) - { - angle0 = 0; - distance0 = 0; - current = false; - this.mp = mp; - } - - public synchronized void setPose(Pose aPose ) - { - setPosition(aPose.getLocation()); - setHeading(aPose.getHeading()); - } - - /** - * called by a MoveProvider when movement ends - * @param move - the event that just started - * @param mp - */ - public void moveStopped(Move move, MoveProvider mp) - { - updatePose(move); - } - - /* - * Update the pose with the incremental movement that has occurred since the - * movementStarted - */ - private synchronized void updatePose(Move event) - { - float angle = event.getAngleTurned() - angle0; - float distance = event.getDistanceTraveled() - distance0; - double dx = 0, dy = 0; - double headingRad = (Math.toRadians(heading)); - - if (event.getMoveType() == Move.MoveType.TRAVEL || Math.abs(angle)<0.2f) - { - dx = (distance) * (float) Math.cos(headingRad); - dy = (distance) * (float) Math.sin(headingRad); - } - else if(event.getMoveType() == Move.MoveType.ARC) - { - double turnRad = Math.toRadians(angle); - double radius = distance / turnRad; - dy = radius * (Math.cos(headingRad) - Math.cos(headingRad + turnRad)); - dx = radius * (Math.sin(headingRad + turnRad) - Math.sin(headingRad)); - } - x += dx; - y += dy; - heading = normalize(heading + angle); // keep angle between -180 and 180 - angle0 = event.getAngleTurned(); - distance0 = event.getDistanceTraveled(); - current = !event.isMoving(); - } - - /* - * returns equivalent angle between -180 and +180 - */ - private float normalize(float angle) - { - float a = angle; - while (a > 180)a -= 360; - while (a < -180) a += 360; - return a; - } - - private void setPosition(Point p) - { - x = p.x; - y = p.y; - current = true; - } - - private void setHeading(float heading) - { - this.heading = heading; - current = true; - } - - @Override - public int sampleSize() { - return 3; - } - - @Override - public void fetchSample(float[] sample, int offset) { - if (!current ) - { - updatePose(mp.getMovement()); - } - sample[offset+0] = x; - sample[offset+1] = y; - sample[offset+2] = heading; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/PoseProvider.java b/ev3classes/src/main/java/lejos/robotics/localization/PoseProvider.java deleted file mode 100644 index 94d53d2..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/PoseProvider.java +++ /dev/null @@ -1,15 +0,0 @@ -package lejos.robotics.localization; - -import lejos.robotics.navigation.Pose; - -/** - * Provides the coordinate and heading info via a Pose object. - * @author NXJ Team - * - */ -public interface PoseProvider { - - public Pose getPose(); - - public void setPose(Pose aPose); -} diff --git a/ev3classes/src/main/java/lejos/robotics/localization/package-info.java b/ev3classes/src/main/java/lejos/robotics/localization/package-info.java deleted file mode 100644 index 927ef1d..0000000 --- a/ev3classes/src/main/java/lejos/robotics/localization/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Localization support - */ -package lejos.robotics.localization; diff --git a/ev3classes/src/main/java/lejos/robotics/mapping/EV3NavigationModel.java b/ev3classes/src/main/java/lejos/robotics/mapping/EV3NavigationModel.java deleted file mode 100644 index 8eb0895..0000000 --- a/ev3classes/src/main/java/lejos/robotics/mapping/EV3NavigationModel.java +++ /dev/null @@ -1,620 +0,0 @@ -package lejos.robotics.mapping; - -import java.io.IOException; -import java.util.ArrayList; - -import lejos.hardware.Battery; -import lejos.hardware.Sound; -import lejos.hardware.motor.Motor; -import lejos.remote.nxt.NXTCommConnector; -import lejos.remote.nxt.NXTConnection; -import lejos.remote.nxt.SocketConnector; -import lejos.robotics.RangeScanner; -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RotatingRangeScanner; -import lejos.robotics.localization.*; -import lejos.robotics.navigation.*; -import lejos.robotics.objectdetection.*; -import lejos.robotics.pathfinding.Path; -import lejos.robotics.pathfinding.PathFinder; -import lejos.utility.Delay; -import lejos.utility.PilotProps; - -/** - * NXT version of the navigation model. - * - * All local navigation objects, including pilots, navigators, path finders, - * feature detectors, and range scanners can be added to the model. - * - * Where possible, the model registers itself as an event listener and when the event occurs, - * updates the model and sends the event and the updates to the PC. - * - * A receiver thread receives events from the PC, updates the local model, and uses the navigation - * objects to implement the event if it involves robot behaviour. - * - * There are set methods to set various navigation parameters. - * - * @author Lawrie Griffiths - * - */ -public class EV3NavigationModel extends NavigationModel implements MoveListener, NavigationListener, WaypointListener, FeatureListener { - protected Navigator navigator; // Only one navigator is allowed - protected MoveController pilot; // Only one pilot is allowed - protected PoseProvider pp; // Only one pose provider is allowed - protected ArrayList detectors = new ArrayList(); // Multiple feature detectors allowed - protected PathFinder finder; // Only one local path finder is allowed - protected RangeScanner scanner; // Only one scanner is allowed - protected NavEventListener listener; - - protected float clearance = 10; - protected float maxDistance = 40; - protected boolean autoSendPose = true; - protected boolean sendMoveStart = false, sendMoveStop = true; - - private float oldRange = -1; - private Thread receiver; - private boolean running = true; - - /** - * Create the model and start the receiver thread - */ - public EV3NavigationModel() { - receiver = new Thread(new Receiver()); - receiver.start(); - } - - /** - * Log a message - * - * @param message the message - */ - public void log(String message) { - System.out.println(message); - } - - /** - * Display an error message to the user - * - * @param message the error message - */ - public void error(String message) { - System.out.println(message); - } - - /** - * Display a fatal error and shut down the program - * - * @param message the error message - */ - public void fatal(String message) { - System.out.println(message); - Delay.msDelay(5000); - System.exit(1); - } - - /** - * Add a navigator to the model - * - * @param navigator the path controller - */ - public void addNavigator(Navigator navigator) { - this.navigator = navigator; - navigator.addNavigationListener(this); - addPoseProvider(navigator.getPoseProvider()); - addPilot(navigator.getMoveController()); - } - - /** - * Add a pilot to the model - * - * @param pilot the move controller - */ - public void addPilot(MoveController pilot) { - this.pilot = pilot; - pilot.addMoveListener(this); - } - - /** - * Add a pose provider (which might be MCL) to the model - * - * @param pp the pose provider - */ - public void addPoseProvider(PoseProvider pp) { - this.pp = pp; - if (pp instanceof MCLPoseProvider) { - mcl = (MCLPoseProvider) pp; - scanner = mcl.getScanner(); - } - } - - /** - * Add a range scanner to the model - * - * @param scanner the range scanner - */ - public void addRangeScanner(RangeScanner scanner) { - this.scanner = scanner; - } - - /** - * Add a feature detector to the model - * - * @param detector the feature detector - */ - public void addFeatureDetector(FeatureDetector detector) { - detectors.add(detector); - detector.addListener(this); - } - - /** - * Set parameters for a random move - * - * @param maxDistance the maximum distance of the move - * @param clearance the clearance distance around the robot - */ - public void setRandomMoveParameters(float maxDistance, float clearance) { - this.maxDistance = maxDistance; - this.clearance = clearance; - } - - /** - * Set or unset automatic sending of the robot pose to the PC when a move stops - * - * @param on true if the pose is to be sent, else false - */ - public void setAutoSendPose(boolean on) { - this.autoSendPose = on; - } - - /** - * Sets whether events are sent to the PC when a move stops - * - * @param on true iff an event should be sent - */ - public void setSendMoveStart(boolean on) { - sendMoveStart = on; - } - - /** - * Sets whether events are sent to the PC when a move starts - * - * @param on true iff an event should be sent - */ - public void setSendMoveStop(boolean on) { - sendMoveStop = on; - } - - /** - * Shut down the receiver thread - */ - public void shutDown() { - running = false; - } - - public void addListener(NavEventListener listener) { - this.listener = listener; - } - - /** - * The Receiver thread receives events from the PC - * - * @author Lawrie Griffiths - * - */ - class Receiver implements Runnable { - public void run() { - //NXTCommConnector connector = Bluetooth.getNXTCommConnector(); - NXTCommConnector connector = new SocketConnector(); - NXTConnection conn = connector.waitForConnection(0, NXTConnection.PACKET); - dis = conn.openDataInputStream(); - dos = conn.openDataOutputStream(); - if (listener != null) listener.whenConnected(); - if (debug) log("Connected"); - while(running) { - try { - // Wait for any outstanding apply moves - if (mcl != null && mcl.isBusy()) Thread.yield(); - byte event = dis.readByte(); - NavEvent navEvent = NavEvent.values()[event]; - if (debug) log(navEvent.name()); - if (listener != null) listener.eventReceived(navEvent); - - synchronized(this) { - switch (navEvent) { - case LOAD_MAP: // Map sent from PC - if (map == null) map = new LineMap(); - map.loadObject(dis); - if (mcl != null) mcl.setMap(map); - break; - case GOTO: // Update of target and request to go to the new target - if (target == null) target = new Waypoint(0,0); - target.loadObject(dis); - if (navigator != null)navigator.goTo(target); - break; - case STOP: // Request to stop the robot - if (navigator != null) navigator.stop(); - if (pilot != null) pilot.stop(); - break; - case TRAVEL: // Request to travel a given distance - float distance = dis.readFloat(); - if (pilot != null) pilot.travel(distance,false); - break; - case ROTATE: // Request to rotate a given angle - float angle = dis.readFloat(); - if (pilot != null && pilot instanceof RotateMoveController) ((RotateMoveController) pilot).rotate(angle,false); - break; - case ARC: // Request to travel an arc og given radius and angle - float radius = dis.readFloat(); - angle = dis.readFloat(); - if (pilot != null && pilot instanceof ArcMoveController) ((ArcMoveController) pilot).arc(radius,angle,false); - break; - case ROTATE_TO: // Request to rotate to a given angle - angle = dis.readFloat(); - if (pp != null && pilot != null && pilot instanceof RotateMoveController) ((RotateMoveController) pilot).rotate(angleTo(angle),false); - break; - case GET_POSE: // Request to get the pose and return it to the PC - if (pp == null) break; - // Suppress sending moves to PC while taking readings - boolean saveSendMoveStart = sendMoveStart; - boolean saveSendMoveStop = sendMoveStop; - sendMoveStart = false; - sendMoveStop = false; - currentPose = pp.getPose(); - sendMoveStart = saveSendMoveStart; - sendMoveStop = saveSendMoveStop; - dos.writeByte(NavEvent.SET_POSE.ordinal()); - currentPose.dumpObject(dos); - break; - case SET_POSE: // Request to set the current pose of the robot - if (currentPose == null) currentPose = new Pose(0,0,0); - currentPose.loadObject(dis); - if (pp != null) pp.setPose(currentPose); - break; - case ADD_WAYPOINT: // Request to add a waypoint - Waypoint wp = new Waypoint(0,0); - wp.loadObject(dis); - if (navigator != null) navigator.addWaypoint(wp); - break; - case FIND_CLOSEST: // Request to find particle by co-ordinates and - // send its details to the PC - float x = dis.readFloat(); - float y = dis.readFloat(); - if (particles != null) { - dos.writeByte(NavEvent.CLOSEST_PARTICLE.ordinal()); - particles.dumpClosest(readings, dos, x, y); - } - break; - case PARTICLE_SET: // Particle set sent from PC - if (map == null) map = new LineMap(); - if (particles == null) particles = new MCLParticleSet(map,0,0); - particles.loadObject(dis); - mcl.setParticles(particles); - break; - case TAKE_READINGS: // Request to take range readings and send them to the PC - if (scanner != null) { - readings = scanner.getRangeValues(); - readings.printReadings(); - dos.writeByte(NavEvent.RANGE_READINGS.ordinal()); - readings.dumpObject(dos); - } - break; - case GET_READINGS: // Request to send current readings to the PC - dos.writeByte(NavEvent.RANGE_READINGS.ordinal()); - if (mcl != null) readings = mcl.getRangeReadings(); - readings.dumpObject(dos); - break; - case GET_PARTICLES: // Request to send particles to the PC - if (particles == null) break; - if (debug) log("Sending particle set"); - synchronized (particles) { - dos.writeByte(NavEvent.PARTICLE_SET.ordinal()); - particles.dumpObject(dos); - } - if (debug) log("Sent particle set"); - break; - case GET_ESTIMATED_POSE: // Request to send estimated pose to the PC - if (mcl == null) break; - dos.writeByte(NavEvent.ESTIMATED_POSE.ordinal()); - mcl.dumpObject(dos); - break; - case FIND_PATH: // Find a path to the target - if (target == null) target = new Waypoint(0,0); - target.loadObject(dis); - if (finder != null) { - dos.writeByte(NavEvent.PATH.ordinal()); - try { - path = finder.findRoute(currentPose, target); - path.dumpObject(dos); - } catch (DestinationUnreachableException e) { - dos.writeInt(0); - } - } - break; - case FOLLOW_PATH: // Follow a route sent from the PC - if (path == null) path = new Path(); - path.loadObject(dis); - if (navigator != null) navigator.followPath(path); - break; - case START_NAVIGATOR: - if (navigator != null) navigator.followPath(); - break; - case CLEAR_PATH: // Clear the current path in the navigator - if (navigator != null) navigator.clearPath(); - break; - case RANDOM_MOVE: // Request to make a random move - randomMove(); - break; - case LOCALIZE: - localize(); - break; - case EXIT: - System.exit(0); - case SOUND: - Sound.systemSound(false, dis.readInt()); - break; - case GET_BATTERY: - dos.writeByte(NavEvent.BATTERY.ordinal()); - dos.writeFloat(Battery.getVoltage()); - dos.flush(); - break; - case PILOT_PARAMS: - float wheelDiameter = dis.readFloat(); - float trackWidth = dis.readFloat(); - int leftMotor = dis.readInt(); - int rightMotor = dis.readInt(); - boolean reverse = dis.readBoolean(); - PilotProps props = new PilotProps(); - String[] motors = {"A","B","C"}; - props.setProperty(PilotProps.KEY_WHEELDIAMETER,"" + wheelDiameter); - props.setProperty(PilotProps.KEY_TRACKWIDTH,"" + trackWidth); - props.setProperty(PilotProps.KEY_LEFTMOTOR,motors[leftMotor]); - props.setProperty(PilotProps.KEY_RIGHTMOTOR,motors[rightMotor]); - props.setProperty(PilotProps.KEY_REVERSE,"" + reverse); - props.storePersistentValues(); - break; - case RANGE_FEATURE_DETECTOR_PARAMS: - int delay = dis.readInt(); - float maxDist = dis.readFloat(); - for (FeatureDetector detector : detectors) { - if (detector instanceof RangeFeatureDetector) { - ((RangeFeatureDetector) detector).setDelay(delay); - ((RangeFeatureDetector) detector).setMaxDistance(maxDist); - } - } - break; - case RANGE_SCANNER_PARAMS: - int gearRatio = dis.readInt(); - int headMotor = dis.readInt(); - RegulatedMotor[] regulatedMotors = {Motor.A, Motor.B, Motor.C}; - if (scanner instanceof RotatingRangeScanner) { - ((RotatingRangeScanner) scanner).setGearRatio(gearRatio); - ((RotatingRangeScanner) scanner).setHeadMotor(regulatedMotors[headMotor]); - } - break; - case TRAVEL_SPEED: - float travelSpeed = dis.readFloat(); - if (pilot != null) pilot.setLinearSpeed(travelSpeed); - break; - case ROTATE_SPEED: - float rotateSpeed = dis.readFloat(); - if (pilot != null && pilot instanceof RotateMoveController) { - ((RotateMoveController)pilot).setAngularSpeed(rotateSpeed); - } - break; - case RANDOM_MOVE_PARAMS: - maxDistance = dis.readFloat(); - clearance = dis.readFloat(); - break; - } - } - } catch (IOException ioe) { - fatal("IOException in receiver:"); - } - } - } - - private void randomMove() { - if (pilot != null && pilot instanceof RotateMoveController) { - float angle = (float) Math.random() * 360; - float distance = (float) Math.random() * maxDistance; - readings = mcl.getReadings(); - - if (angle > 180f) angle -= 360f; - - float forwardRange; - // Get forward range - try { - forwardRange = readings.getRange(0f); // Range for angle 0 (forward) - } catch (Exception e) { - forwardRange = 0; - } - - // Don't move forward if we are near a wall - if (forwardRange < 0 - || distance + clearance < forwardRange) - pilot.travel(distance,false); - - if (debug) log("Random moved started"); - ((RotateMoveController) pilot).rotate(angle,false); - if (debug) log("Random moved done"); - } - } - - private void localize() { - boolean saveSendMoveStart = sendMoveStart; - boolean saveSendMoveStop = sendMoveStop; - sendMoveStart = false; - sendMoveStop = false; - while (true) { - try { - mcl.getPose(); - dos.writeByte(NavEvent.PARTICLE_SET.ordinal()); - particles.dumpObject(dos); - readings = mcl.getReadings(); - dos.writeByte(NavEvent.RANGE_READINGS.ordinal()); - readings.dumpObject(dos); - if (goodEstimate()) { - // Send the estimate to the PC - dos.writeByte(NavEvent.ESTIMATED_POSE.ordinal()); - mcl.dumpObject(dos); - dos.writeByte(NavEvent.LOCATED.ordinal()); - dos.flush(); - break; - } - randomMove(); - dos.writeByte(NavEvent.PARTICLE_SET.ordinal()); - particles.dumpObject(dos); - } catch (IOException ioe) { - fatal("IOException in localize"); - } - } - sendMoveStart = saveSendMoveStart; - sendMoveStop = saveSendMoveStop; - } - - private boolean goodEstimate() { - //float sx = mcl.getSigmaX(); - //float sy = mcl.getSigmaY(); - float xr = mcl.getXRange(); - float yr = mcl.getYRange(); - return xr < 50 && yr < 50 ; - } - - // Calculate the angle for ROTATE_TO - private int angleTo(float angle) { - int angleTo = ((int) (angle - pp.getPose().getHeading())) % 360; - return (angleTo < 180 ? angleTo : angleTo - 360); - } - } - - /** - * Called when the pilot starts a move - */ - public void moveStarted(Move event, MoveProvider mp) { - if (!sendMoveStart) return; - try { - synchronized(receiver) { - if (debug) log("Sending move started"); - dos.writeByte(NavEvent.MOVE_STARTED.ordinal()); - event.dumpObject(dos); - } - } catch (IOException ioe) { - fatal("IOException in moveStarted"); - } - } - - /** - * Called when a move stops - */ - public void moveStopped(Move event, MoveProvider mp) { - if (!sendMoveStop) return; - try { - synchronized(receiver) { - if (debug) log("Sending move stopped"); - dos.writeByte(NavEvent.MOVE_STOPPED.ordinal()); - event.dumpObject(dos); - if (pp != null && autoSendPose) { - if (debug) log("Sending set pose"); - dos.writeByte(NavEvent.SET_POSE.ordinal()); - pp.getPose().dumpObject(dos); - } - if (debug) log("Move stopped sent"); - } - } catch (IOException ioe) { - fatal("IOException in moveStopped"); - } - } - - /** - * Called when a feature is detected. - * Only range features currently supported - */ - public void featureDetected(Feature feature, FeatureDetector detector) { - if (dos == null) return; - if (!(feature instanceof RangeFeature)) return; - float range = ((RangeFeature) feature).getRangeReading().getRange(); - if (range < 0) return; - if (pilot == null || !pilot.isMoving()) { - if (range == oldRange) return; - } - oldRange = range; - try { - synchronized(receiver) { - dos.writeByte(NavEvent.FEATURE_DETECTED.ordinal()); - ((RangeFeature) feature).dumpObject(dos); - } - } catch (IOException ioe) { - fatal("IOException in featureDetected"); - } - } - - /** - * Send a waypoint generated on the NXT to the PC - */ - public void addWaypoint(Waypoint wp) { - try { - synchronized(receiver) { - dos.writeByte(NavEvent.ADD_WAYPOINT.ordinal()); - // TODO: send waypoint to the PC - dos.flush(); - } - } catch (IOException ioe) { - fatal("IOException in addWaypoint"); - } } - - /** - * Called when a waypoint has been reached - */ - public void atWaypoint(Waypoint waypoint, Pose pose, int sequence) { - try { - synchronized(receiver) { - dos.writeByte(NavEvent.WAYPOINT_REACHED.ordinal()); - waypoint.dumpObject(dos); - } - } catch (IOException ioe) { - fatal("IOException in atWaypoint"); - } - } - - /** - * Called when a path has been completed - */ - public void pathComplete(Waypoint waypoint, Pose pose, int sequence) { - try { - synchronized(receiver) { - dos.writeByte(NavEvent.PATH_COMPLETE.ordinal()); - dos.flush(); - } - } catch (IOException ioe) { - fatal("IOException in pathComplete"); - } - } - - /** - * Called when a path has been interrupted - */ - public void pathInterrupted(Waypoint waypoint, Pose pose, int sequence) { - try { - synchronized(receiver) { - dos.writeByte(NavEvent.PATH_INTERRUPTED.ordinal()); - dos.flush(); - } - } catch (IOException ioe) { - fatal("IOException in pathInterrupted"); - } - } - - /** - * Called when a path finder has finished generating a path - */ - public void pathGenerated() { - try { - synchronized(receiver) { - dos.writeByte(NavEvent.PATH_GENERATED.ordinal()); - dos.flush(); - } - } catch (IOException ioe) { - fatal("IOException in pathGenerated"); - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/mapping/LineMap.java b/ev3classes/src/main/java/lejos/robotics/mapping/LineMap.java deleted file mode 100644 index f497d4a..0000000 --- a/ev3classes/src/main/java/lejos/robotics/mapping/LineMap.java +++ /dev/null @@ -1,179 +0,0 @@ -package lejos.robotics.mapping; - -import java.io.*; - -import lejos.robotics.Transmittable; -import lejos.robotics.geometry.*; -import lejos.robotics.mapping.RangeMap; -import lejos.robotics.navigation.Pose; - - -/** - * A map of a room or other closed environment, represented by line segments - * - * @author Lawrie Griffiths - * - */ -public class LineMap implements RangeMap, Transmittable { - private Line[] lines; - private Rectangle boundingRect; - - /** - * Calculate the range of a robot to the nearest wall - * - * @param pose the pose of the robot - * @return the range or -1 if not in range - */ - public float range(Pose pose) { - Line l = new Line(pose.getX(), pose.getY(), pose.getX() + 254f - * (float) Math.cos(Math.toRadians(pose.getHeading())), pose.getY() + 254f - * (float) Math.sin(Math.toRadians(pose.getHeading()))); - Line rl = null; - - for (int i = 0; i < lines.length; i++) { - Point p = lines[i].intersectsAt(l); - if (p == null) continue; // Does not intersect - Line tl = new Line(pose.getX(), pose.getY(), p.x, p.y); - - // If the range line intersects more than one map line - // then take the shortest distance. - if (rl == null || tl.length() < rl.length()) rl = tl; - } - return (rl == null ? -1 : rl.length()); - } - - /** - * Create a map from an array of line segments and a bounding rectangle - * - * @param lines the line segments - * @param boundingRect the bounding rectangle - */ - public LineMap(Line[] lines, Rectangle boundingRect) { - this.lines = lines; - this.boundingRect = boundingRect; - } - - /** - * Constructor to use when map will be loaded from a data stream - */ - public LineMap() { - } - - /** - * Check if a point is within the mapped area - * - * @param p the Point - * @return true iff the point is with the mapped area - */ - public boolean inside(Point p) { - if (p.x < boundingRect.x || p.y < boundingRect.y) return false; - if (p.x > boundingRect.x + boundingRect.width - || p.y > boundingRect.y + boundingRect.height) return false; - - // Create a line from the point to the left - Line l = new Line(p.x, p.y, p.x - boundingRect.width, p.y); - - // Count intersections - int count = 0; - for (int i = 0; i < lines.length; i++) { - if (lines[i].intersectsAt(l) != null) count++; - } - // We are inside if the number of intersections is odd - return count % 2 == 1; - } - - /** - * Return the bounding rectangle of the mapped area - * - * @return the bounding rectangle - */ - public Rectangle getBoundingRect() { - return boundingRect; - } - - /** - * Dump the map to a DataOutputStream - * @param dos the stream - * @throws IOException - */ - public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeInt(lines.length); - for(int i=0;i"); - ps.println(""); - for(int i=0;i"); - } - ps.println(""); - ps.println(""); - ps.close(); - fos.close(); - } - - /** - * Create a line map with the y axis flipped - * - * @return the new LineMap - */ - public LineMap flip() { - float maxY = boundingRect.y + boundingRect.height; - Line[] ll = new Line[lines.length]; - - for(int i=0;i= occupiedThreshold); - } - - public boolean isFree(int x, int y) { - return(cells[x][y] <= freeThreshold); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/mapping/RangeMap.java b/ev3classes/src/main/java/lejos/robotics/mapping/RangeMap.java deleted file mode 100644 index d462259..0000000 --- a/ev3classes/src/main/java/lejos/robotics/mapping/RangeMap.java +++ /dev/null @@ -1,39 +0,0 @@ -package lejos.robotics.mapping; - -import lejos.robotics.geometry.*; -import lejos.robotics.navigation.Pose; - - -/** - * The RangeMap interface supports determining the range to a feature on the map - * (such as a wall), from an object with a specific pose. - * - * It also supports the a method to determine if a point is within the mapped - * area. - * - * @author Lawrie Griffiths - * - */ -public interface RangeMap { - /** - * The the range to the nearest wall (or other feature) - * @param pose the pose of the robot - * @return the range - */ - public float range(Pose pose); - - /** - * Test if a point is within the mapped area - * - * @param p the point - * @return true iff the point is within the mapped area - */ - public boolean inside(Point p); - - /** - * Get the bounding rectangle for the mapped area - * - * @return the bounding rectangle - */ - public Rectangle getBoundingRect(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/mapping/SVGMapLoader.java b/ev3classes/src/main/java/lejos/robotics/mapping/SVGMapLoader.java deleted file mode 100644 index 4bc1695..0000000 --- a/ev3classes/src/main/java/lejos/robotics/mapping/SVGMapLoader.java +++ /dev/null @@ -1,61 +0,0 @@ -package lejos.robotics.mapping; - -import java.io.InputStream; -import java.util.ArrayList; - -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamConstants; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; - -import lejos.robotics.geometry.Line; -import lejos.robotics.geometry.Rectangle; - -/** - *

    This class loads map data from an SVG and produces a LineMap object, which can - * be used by the leJOS navigation package.

    - * - * @author Lawrie Griffiths/Juan Antonio Brenha Moral - * - */ -public class SVGMapLoader { - private static final float MAX_BOUND = 10000f; // Bounds must be smaller than this - - private InputStream in = null; - - public SVGMapLoader(InputStream in) { - this.in = in; - } - - public LineMap readLineMap() throws XMLStreamException { - XMLInputFactory factory = XMLInputFactory.newInstance(); - XMLStreamReader parser = factory.createXMLStreamReader(in); - ArrayList lines = new ArrayList(); - float minX = MAX_BOUND, minY = MAX_BOUND, maxX = 0f, maxY = 0f; - - while (true) { - int event = parser.next(); - if (event == XMLStreamConstants.END_DOCUMENT) { - parser.close(); - break; - } else if (event == XMLStreamConstants.START_ELEMENT && parser.getLocalName().equals("line")) { - float x1 = Float.parseFloat(parser.getAttributeValue(null,"x1")); - float y1 = Float.parseFloat(parser.getAttributeValue(null,"y1")); - float x2 = Float.parseFloat(parser.getAttributeValue(null,"x2")); - float y2 = Float.parseFloat(parser.getAttributeValue(null,"y2")); - if (x1 < minX) minX = x1; - if (x2 < minX)minX = x2; - if (x1 > maxX) maxX = x1; - if (x2 > maxX) maxX = x2; - if (y1 < minY) minY = y1; - if (y2 < minY) minY = y2; - if (y1 > maxY) maxY = y1; - if (y2 > maxY) maxY = y2; - - lines.add(new Line(x1,y1,x2,y2)); - } - } - - return new LineMap(lines.toArray(new Line[lines.size()]), new Rectangle(minX, minY, maxX - minX, maxY - minY )).flip(); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/mapping/ShapefileLoader.java b/ev3classes/src/main/java/lejos/robotics/mapping/ShapefileLoader.java deleted file mode 100644 index 51b63fb..0000000 --- a/ev3classes/src/main/java/lejos/robotics/mapping/ShapefileLoader.java +++ /dev/null @@ -1,229 +0,0 @@ -package lejos.robotics.mapping; - -import java.io.*; -import java.util.ArrayList; - -import lejos.robotics.geometry.Line; -import lejos.robotics.geometry.Rectangle; - - -/** - *

    This class loads map data from a Shapefile and produces a LineMap object, which can - * be used by the leJOS navigation package.

    - * - *

    There are many map editors which can use the Shapefile format (OpenEV, Global Mapper). Once you - * have created a map, export it as Shapefile. This will produce three files ending in .shp .shx and - * .dbf. The only file used by this class is .shp.

    - * - *

    NOTE: Shapefiles can only contain one type of shape data (polygon or polyline, not both). A single file can't - * mix polylines with polygons.

    - * - *

    This class' code can parse points and multipoints. However, a LineMap object can't deal with - * points (only lines) so points and multipoints are discarded.

    - * - * @author BB - * - */ -public class ShapefileLoader { - - /* OTHER POTENTIAL MAP FILE FORMATS TO ADD: - * (none have really been researched yet for viability) - * KML - * GML - * WMS? (more of a service than a file) - * MIF/MID (MapInfo) - * SVG (Scalable Vector Graphics) - * EPS (Encapsulated Post Script) - * DXF (Autodesk) - * AI (Adobe Illustrator) - * - */ - - // 2D shape types types: - private static final byte NULL_SHAPE = 0; - private static final byte POINT = 1; - private static final byte POLYLINE = 3; - private static final byte POLYGON = 5; - private static final byte MULTIPOINT = 8; - - private final int SHAPEFILE_ID = 0x0000270a; - DataInputStream data_is = null; - - /** - * Creates a ShapefileLoader object using an input stream. Likely you will use a FileInputStream - * which points to the *.shp file containing the map data. - * @param in - */ - public ShapefileLoader(InputStream in) { - this.data_is = new DataInputStream(in); - } - - /** - * Retrieves a LineMap object from the Shapefile input stream. - * @return the line map - * @throws IOException - */ - public LineMap readLineMap() throws IOException { - ArrayList lines = new ArrayList (); - - int fileCode = data_is.readInt(); // Big Endian - if(fileCode != SHAPEFILE_ID) throw new IOException("File is not a Shapefile"); - data_is.skipBytes(20); // Five int32 unused by Shapefile - /*int fileLength =*/ data_is.readInt(); - //System.out.println("Length: " + fileLength); // TODO: Docs say length is in 16-bit words. Unsure if this is strictly correct. Seems higher than what hex editor shows. - /*int version =*/ readLEInt(); - //System.out.println("Version: " + version); - /*int shapeType =*/ readLEInt(); - //System.out.println("Shape type: " + shapeType); - // These x and y min/max values define bounding rectangle: - double xMin = readLEDouble(); - double yMin = readLEDouble(); - double xMax = readLEDouble(); - double yMax = readLEDouble(); - // Create bounding rectangle: - Rectangle rect = new Rectangle((float)xMin, (float)yMin, (float)(xMax - xMin), (float)(yMax - yMin)); - /*double zMin =*/ readLEDouble(); - /*double zMax =*/ readLEDouble(); - /*double mMin =*/ readLEDouble(); - /*double mMax =*/ readLEDouble(); - // TODO These values seem to be rounded down to nearest 0.5. Must round them up? - //System.out.println("Xmin " + xMin + " Ymin " + yMin); - //System.out.println("Xmax " + xMax + " Ymax " + yMax); - - try { // TODO: This is a cheesy way to detect EOF condition. Not very good coding. - while(2 > 1) { // TODO: Temp code to keep it looping. Should really detect EOF condition. - - // NOW ONTO READING INDIVIDUAL SHAPES: - // Record Header (2 values): - /*int recordNum =*/ data_is.readInt(); - int recordLen = data_is.readInt(); // TODO: in 16-bit words. Might cause bug if number of shapes gets bigger than 16-bit short? - - // Record (variable length depending on shape type): - int recShapeType = readLEInt(); - - // Now to read the actual shape data - switch (recShapeType) { - case NULL_SHAPE: - break; - case POINT: - // DO WE REALLY NEED TO DEAL WITH POINT? Feature might use them possibly. - /*double pointX =*/ readLEDouble(); // TODO: skip bytes instead - /*double pointY =*/ readLEDouble(); - break; - case POLYLINE: - // NOTE: Data structure for polygon/polyline is identical. Code should work for both. - case POLYGON: - // Polygons can contain multiple polygons, such as a donut with outer ring and inner ring for hole. - // Max bounding rect: 4 doubles in a row. TODO: Discard bounding rect. values and skip instead. - /*double polyxMin =*/ readLEDouble(); - /*double polyyMin =*/ readLEDouble(); - /*double polyxMax =*/ readLEDouble(); - /*double polyyMax =*/ readLEDouble(); - int numParts = readLEInt(); - int numPoints = readLEInt(); - - // Retrieve array of indexes for each part in the polygon - int [] partIndex = new int[numParts]; - for(int i=0;i=PATHS/2) radius = -turnRadius; // Do calculations for +ve radius then -ve radius - - // Find two arc angles: - Point c = ArcAlgorithms.findCircleCenter(p1, radius, start.getHeading()); - Point p2 = ArcAlgorithms.findP2(c, p3, radius); - float arcLengthForward = ArcAlgorithms.getArc(p1, p2, radius, start.getHeading(), true); - //double arcLengthBackward = ArcAlgorithms.getArc(p1, p2, radius, start.getHeading(), false); - float arcLengthBackward = ArcAlgorithms.getArcBackward(arcLengthForward); // faster - - // Find straight line: - double z = ArcAlgorithms.distBetweenPoints(c, p3); - double p2p3 = ArcAlgorithms.distP2toP3(radius, z); - - paths[i][0] = new Move(false, arcLengthForward, radius); - paths[i][1] = new Move((float)p2p3, 0, false); - i++; - paths[i][0] = new Move(false, arcLengthBackward, radius); - paths[i][1] = new Move((float)p2p3, 0, false); - } - - return paths; - } - - /** - * This method generates the shortest path from a starting Pose to a final Point. The final heading - * is indeterminate at the destination. To arrive at the destination, the robot drives an arc, then a straight line - * to the destination point. - * - * @param start The starting Pose - * @param destination The destination Point - * @param radius The turn radius - * @return The shortest available path (given the parameters). - */ - public static Move [] getBestPath(Pose start, Point destination, float radius) { - // Get all paths - Move [][] paths = getAvailablePaths(start, destination, radius); - return getBestPath(paths); - } - - /** - * This helper method accepts a number of paths (an array of Move) and selects the shortest path. - * @param paths Any number of paths. - * @return The shortest path. - */ - public static Move [] getBestPath(Move [][] paths) { - /* TODO: Note, the space-search algorithm that finds the shortest path should only drive the straight - * segment in reverse IF the distance is 1/2 the circumference of the minimum circle. The reasoning is that - * the vehicle will drive a maximum distance of 1/2 circumference for the arc turn, so the same distance in - * reverse for the straight segment is also acceptable. Later, when the circles at the target location are - * factored in, this will also have some sort of effect on the final solution. - */ - - Move [] bestPath = null; - - // Now see which one has shortest travel distance: - float minDistance = Float.POSITIVE_INFINITY; - for(int i=0;i1 when it should not have been. This is a kludge to fix that: - if(angle < -1 & angle > -1.1) angle = -1; - if(angle > 1 & angle < 1.1) angle = 1; - - angle = Math.acos(angle); - return (float)Math.toDegrees(angle); - } - - /** - * Given the former heading and the change in heading, this method will calculate a new heading. - * @param oldHeading The old heading (original heading of robot) in degrees - * @param changeInHeading The change in angle, in degrees. - * @return The new heading, in degrees. (0 to 360) - */ - public static float getHeading(float oldHeading, float changeInHeading) { - float heading = oldHeading + changeInHeading; - if(heading >=360) heading -= 360; - if(heading <0) heading += 360; - return heading; - } - - /** - * If p1 is the starting point of the robot, and p2 is the point at which the robot is pointing - * directly at the target point, this method calculates the angle to travel along the circle (an arc) - * to get from p1 to p2. - * - * @param p1 Start position - * @param p2 Take-off point on the circle - * @param radius Radius of circle AKA the turnRadius - * @param heading Start heading vehicle is pointed, in degrees. - * @param forward Will the vehicle be moving forward along the circle arc? - * @return Length of travel along circle, in degrees - * - */ - public static float getArc(Point p1, Point p2, float radius, float heading, boolean forward) { - // I accidently got the radius sign confused. +ve radius is supposed to have circle center to left of robot: - radius = -radius; // Kludge. Should really correct my equations. - - Point pa = ArcAlgorithms.findPointOnHeading(p1, heading, radius*2); - float arcLength = ArcAlgorithms.getTriangleAngle(p1, p2, pa); - arcLength *= -2; - - // TODO: Bit of a hack here. Math should be able to do it without conditional if-branches - if(radius < 0) arcLength = 360 + arcLength; - if(!forward) { - // TODO: This 'if' could really be amalgamated with the if(radius < 0) branch - if(arcLength < 0) - arcLength = arcLength + 360; - else - arcLength = arcLength - 360; - } - return arcLength; - } - - /** - * Quick calculation of reverse arc instead of going through getArcLength() math again. - * @param forwardArc - * @return the backward arc - */ - public static float getArcBackward(float forwardArc) { - float backwardArc = 0; - - if(forwardArc < 0) - backwardArc = 360 + forwardArc; - else if(forwardArc > 0) - backwardArc = -360 + forwardArc; - - return backwardArc; - } - - - /** - * - * If p1 is the starting point of the robot, and p2 is the point at which the robot is pointing - * directly at the target point, this method calculates the angle to travel along the circle (an arc) - * to get from p1 to p2. - * - * @param p1 Start position - * @param p2 Take-off point on circle - * @param radius Radius of circle - * @return Length of travel along circle, in degrees - * @deprecated This method is no longer used because it can't calculate >180 angles. Delete any time. - */ - @Deprecated - public static double getArcOld(Point p1, Point p2, double radius) { - // I accidently got the radius sign confused. +ve radius is supposed to have circle center to left of robot: - radius = -radius; // Kludge. Should really correct my equations. - - // This equation can't generate angles >180 (the major angle), so if angle is actually >180 it will - // generate the minor angle rather than the major angle. - double d = distBetweenPoints(p1, p2); - - // The - in front of 2 below is a temp hack. Won't work for reverse movements by robot. - double angle = -2 * Math.asin(d / (2 * radius)); - return Math.toDegrees(angle); - } - - /** - * Assume p2 is the "takeoff" point and p3 is the final target point, this private helper method is used to - * calculate the distance between p2 to p3, given only the radius and an intermediate value z. The methods findP2() - * and getAvailablePaths() both use this method. - * - * @param radius The turn radius of the vehicle. - * @param z An intermediate value. - * @return - */ - private static double distP2toP3(double radius, double z) { - double x = Math.pow(z, 2) - Math.pow(radius, 2); - return Math.sqrt(x); - } - - /** - * Calculates the distance between any two points. - * - * @param a The first point - * @param b The second point - * @return The distance between points a and b. - */ - public static float distBetweenPoints(Point a, Point b) { - // TODO: Should delete this method, just use Point2D. - return (float) Point2D.distance(a.x, a.y, b.x, b.y); - //double z = Math.pow((b.x - a.x), 2) + Math.pow((b.y - a.y), 2); - //return (float)Math.sqrt(z); - } - - /** - * Calculates the heading designated by two points. Heading always travels from the "from" point - * to the "to" point. - * - * @param from Starting point. - * @param to Final point. - * @return Heading in degrees (0-360) - */ - public static float getHeading(Point from, Point to) { - Point xAxis = new Point(from.x + 30, from.y); - float heading = ArcAlgorithms.getTriangleAngle(from, to, xAxis); - if(to.y < from.y) heading = 360 - heading; - return heading; - } - - /** - * This method finds P2 if the vehicle is traveling to a point (with no heading). - * - * @param c The center point of the turning circle. - * @param p3 The final target point - * @param radius The turn radius. - * @return P2, the takeoff point on the circle. - */ - public static Point findP2(Point c, Point p3, float radius) { - // I accidently got the radius sign confused. +ve radius is supposed to have circle center to left of robot: - radius = -radius; // Kludge. Should really correct my equations. - - double z = distBetweenPoints(c, p3); - double a1 = p3.x - c.x; - double o = p3.y - c.y; - double angle = Math.atan2(o , a1) - Math.asin(radius / z); - - double x = distP2toP3(radius, z); - double a2 = x * Math.cos(angle); - double o1 = x * Math.sin(angle); - - double x2 = p3.x - a2; - double y2 = p3.y - o1; - - return new Point((float)x2, (float)y2); - } - - /** - * Calculates the center of a circle that rests on the tangent of the vehicle's starting heading. - * It can calculate a circle to the right OR left of the heading tangent. - * To calculate a circle on the left side of the heading tangent, feed it a negative radius. - * - * @param p1 the starting point of the vehicle. - * @param radius Turning radius of vehicle. A negative value produces a circle to the right of the heading. - * @param heading Start heading of vehicle, in degrees (not radians). - * @return The center point of the circle. - */ - public static Point findCircleCenter(Point p1, float radius, float heading) { - // I accidently got the radius sign confused. +ve radius is supposed to have circle center to left of robot: - radius = -radius; // TODO: Kludge. Should really correct my equations. - - double t = heading - 90; // TODO: Need to check if > 360 or < 0? Think cos/sin handle it. - - double a = p1.x + radius * Math.cos(Math.toRadians(t)); - double b = p1.y + radius * Math.sin(Math.toRadians(t)); - - return new Point((float)a,(float)b); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/ArcMoveController.java b/ev3classes/src/main/java/lejos/robotics/navigation/ArcMoveController.java deleted file mode 100644 index 229c3cc..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/ArcMoveController.java +++ /dev/null @@ -1,161 +0,0 @@ -package lejos.robotics.navigation; - -/** - * An enhanced MoveController that is capable of traveling in arcs. - * @author NXJ Team - * - */ -public interface ArcMoveController extends MoveController { - - /** - * The minimum steering radius this vehicle is capable of when traveling in an arc. - * Theoretically this should be identical for both forward and reverse travel. In practice? - * - * @return the radius in degrees - */ - public double getMinRadius(); - - /** - * Set the radius of the minimum turning circle. - * - * @param radius the radius in degrees - */ - public void setMinRadius(double radius); - - /** - * Starts the NXT robot moving forward along an arc with a specified radius. - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, the robot rotates in place. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * Note: If you have specified a drift correction in the constructor it will not be applied in this method. - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - */ - public void arcForward(double radius); - - /** - * Starts the NXT robot moving backward along an arc with a specified radius. - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, the robot rotates in place. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * Note: If you have specified a drift correction in the constructor it will not be applied in this method. - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - */ - public void arcBackward(double radius); - - /** - * Moves the NXT robot along an arc with a specified radius and angle, - * after which the robot stops moving. This method does not return until the robot has - * completed moving angle degrees along the arc. - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, is zero, the robot rotates in place. - *

    - * Robot will stop when the degrees it has moved along the arc equals angle.
    - * If angle is positive, the robot will turn to the left (anti-clockwise).
    - * If angle is negative, the robot will turn to the right (clockwise). - * If angle is zero, the robot will not move and the method returns immediately. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * Note: If you have specified a drift correction in the constructor it will not be applied in this method. - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - * @param angle The sign of the angle determines the direction of the robot turns: Positive is anti-clockwise, negative is clockwise. - * @see #travelArc(double, double) - */ - public void arc(double radius, double angle); - - /** - * Moves the NXT robot along an arc with a specified radius and angle, - * after which the robot stops moving. This method has the ability to return immediately - * by using the immediateReturn parameter. - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, is zero, the robot rotates in place. - *

    - * The robot will stop when the degrees it has moved along the arc equals angle.
    - * If angle is positive, the robot will turn to the left (anti-clockwise).
    - * If angle is negative, the robot will turn to the right (clockwise). - * If angle is zero, the robot will not move and the method returns immediately. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * Note: If you have specified a drift correction in the constructor it will not be applied in this method. - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - * @param angle The sign of the angle determines the direction of the robot turns: Positive is anti-clockwise, negative is clockwise. - * @param immediateReturn If immediateReturn is true then the method returns immediately. - * @see #travelArc(double, double, boolean) - */ - public void arc(double radius, double angle, boolean immediateReturn); - - /** - * Moves the NXT robot a specified distance along an arc of specified radius, - * after which the robot stops moving. This method does not return until the robot has - * completed moving distance along the arc. The units (inches, cm) for distance - * must be the same as the units used for radius. - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, the robot rotates in place - *

    - * The robot will stop when it has moved along the arc distance units.
    - * If distance is positive, the robot will move travel forwards.
    - * If distance is negative, the robot will move travel backwards.
    - * If distance is zero, the robot will not move and the method returns immediately. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - * @param distance to travel, in same units as radius. The sign of the distance determines the direction of robot motion. Positive drives the robot forward, negative drives it backward. - * @see #arc(double, double) - * - */ - public void travelArc(double radius, double distance); - - /** - * Moves the NXT robot a specified distance along an arc of specified radius, - * after which the robot stops moving. This method has the ability to return immediately - * by using the immediateReturn parameter. - * The units (inches, cm) for distance should be the same as the units used for radius. - * - *

    - * If radius is positive, the robot arcs left, and the center of the turning circle is on the left side of the robot.
    - * If radius is negative, the robot arcs right, and the center of the turning circle is on the right side of the robot.
    - * If radius is zero, the robot rotates in place. - *

    - * The robot will stop when it has moved along the arc distance units.
    - * If distance is positive, the robot will move travel forwards.
    - * If distance is negative, the robot will move travel backwards.
    - * If distance is zero, the robot will not move and the method returns immediately. - *

    - * Postcondition: Motor speeds are unpredictable. - *

    - * - * @param radius of the arc path. If positive, the left side of the robot is on the inside of the turn. If negative, the left - * side of the robot is on the outside of the turn. - * @param distance to travel, in same units as radius. The sign of the distance determines the direction of robot motion. Positive drives the robot forward, negative drives it backward. - * @param immediateReturn If immediateReturn is true then the method returns immediately. - * @see #arc(double, double, boolean) - * - */ - public void travelArc(double radius, double distance, boolean immediateReturn); -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/ArcRotateMoveController.java b/ev3classes/src/main/java/lejos/robotics/navigation/ArcRotateMoveController.java deleted file mode 100644 index 1971c5e..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/ArcRotateMoveController.java +++ /dev/null @@ -1,8 +0,0 @@ -package lejos.robotics.navigation; - -/** - * A MoveController for robots that can perform arcs and rotate on the spot. - */ -public interface ArcRotateMoveController extends ArcMoveController, RotateMoveController { - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/Ballbot.java b/ev3classes/src/main/java/lejos/robotics/navigation/Ballbot.java deleted file mode 100644 index 2ca0846..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/Ballbot.java +++ /dev/null @@ -1,484 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.hardware.lcd.LCD; -import lejos.hardware.Sound; -import lejos.robotics.EncoderMotor; -import lejos.robotics.Gyroscope; - -/** - *

    This class dynamically stabilizes a ballbot type of robot. The ballbot robot uses two motors to drive a ball - * with a similar configuration to a mechanical mouse.

    - * - *

    A ballbot needs good motors, sensors, a grippy ball/rollers (wheels) and should be as symmetrical as possible in all - * directions (like a circle) to optimize stability. If using a billiard ball or LEGO ball, it is recommended - * to apply a layer of rubber glue to the tires to add grip.

    - * - *

    To start the robot balancing: - *

  • 1. Run the program. You will be prompted to lay it down. - *
  • 2. Lay it down (orientation doesn't matter). When it detects it is not moving it will automatically calibrate the gyro sensors. - *
  • 3. When the beeping begins, stand it up on the ball so it is vertically balanced. - *
  • 4. When the beeping stops, let go and it will begin balancing on its own.

    - * - *

    This code is based on the Segoway class.

    - * - * @author BB - * - */ -public class Ballbot extends Thread { // TODO: Thread should be a private inner class, especially given that Ballbot constructor creates two instances of Ballbot threads. - - /* Developer notes: - * TODO: The Ballbot and Segoway classes could share a lot of the same balance code. Each Ballbot thread uses one motor, - * not two. But most of the code is the same. Possibly extend Segoway and override some methods in new - * Ballbot class. - * - * TODO: Get rid of platform dependencies. - */ - - // Motors and gyro: - private Gyroscope gyro; - protected EncoderMotor my_motor; - //protected EncoderMotor right_motor; // TODO - - //===================================================================== - // Balancing constants - // - // These are the constants used to maintain balance. - //===================================================================== - - /** - * Loop wait time. WAIT_TIME is the time in ms passed to the Wait command. - * NOTE: Balance control loop only takes 1.128 MS in leJOS NXJ to execute. - */ - private static final int WAIT_TIME = 6; // originally 8 - - // These are the main four balance constants, only the gyro - // constants are relative to the wheel size. KPOS and KSPEED - // are self-relative to the wheel size. - private static final double KGYROANGLE = 7.5; - private static final double KGYROSPEED = 1.15; - private static final double KPOS = 0.07; - private static final double KSPEED = 0.1; - - /** - * This constant aids in drive control. When the robot starts moving because of user control, - * this constant helps get the robot leaning in the right direction. Similarly, it helps - * bring robot to a stop when stopping. - */ - private static final double KDRIVE = -0.02; - - /** - * Power differential used for steering based on difference of target steering and actual motor difference. - */ - private static final double KSTEER = 0.25; - - /** - * Gyro offset control - * The gyro sensor will drift with time. This constant is used in a simple long term averaging - * to adjust for this drift. Every time through the loop, the current gyro sensor value is - * averaged into the gyro offset weighted according to this constant. - */ - private static final double EMAOFFSET = 0.0005; - - /** - * If robot power is saturated (over +/- 100) for over this time limit then - * robot must have fallen. In milliseconds. - */ - private static final double TIME_FALL_LIMIT = 500; // originally 1000 - - //--------------------------------------------------------------------- - - /** - * This constant is in degrees/second for maximum speed. Note that position - * and speed are measured as the sum of the two motors, in other words, 600 - * would actually be 300 degrees/second for each motor. - */ - private static final double CONTROL_SPEED = 600.0; - - //===================================================================== - // Global variables - //===================================================================== - - // These two xxControlDrive variables are used to control the movement of the robot. Both - // are in degrees/second: - /** - * motorControlDrive is the target speed for the sum of the two motors - * in degrees per second. - */ - private double motorControlDrive = 0.0; - - /** - * motorControlSteer is the target change in difference for two motors - * in degrees per second. - */ - private double motorControlSteer = 0.0; - - /** - * This global contains the target motor differential, essentially, which - * way the robot should be pointing. This value is updated every time through - * the balance loop based on motorControlSteer. - */ - private double motorDiffTarget = 0.0; - - /** - * Time that robot first starts to balance. Used to calculate tInterval. - */ - private long tCalcStart; - - /** - * tInterval is the time, in seconds, for each iteration of the balance loop. - */ - private double tInterval; - - /** - * ratioWheel stores the relative wheel size compared to a standard NXT 1.0 wheel. - * RCX 2.0 wheel has ratio of 0.7 while large RCX wheel is 1.4. - */ - private double ratioWheel; - - // Gyro globals - private double gOffset; - private double gAngleGlobal = 0; - - // Motor globals - private double motorPos = 0; - private long mrcSum = 0, mrcSumPrev; - private long motorDiff; - private long mrcDeltaP3 = 0; - private long mrcDeltaP2 = 0; - private long mrcDeltaP1 = 0; - - /** - * Creates an instance of the Ballbot, prompts the user to lay Ballbot flat for gyro calibration, - * then begins self-balancing thread. Wheel diameter is used in balancing equations. - * - *
  • NXT 1.0 wheels = 5.6 cm - *
  • NXT 2.0 wheels = 4.32 cm - * - * @param left The left motor. An unregulated motor. - * @param right The right motor. An unregulated motor. - * @param gyro A HiTechnic gyro sensor - * @param wheelDiameter diameter of wheel, preferably use cm (printed on side of LEGO tires in mm) - */ - private Ballbot(EncoderMotor motor, Gyroscope gyro, double wheelDiameter) { // TODO: Wheel diam will be unnecessary? - this.my_motor = motor; - - this.gyro = gyro; - this.ratioWheel = wheelDiameter/5.6; // Original algorithm was tuned for 5.6 cm NXT 1.0 wheels. - - // Took out 50 ms delay here. - - // Get the initial gyro offset - getGyroOffset(); - } - - /** - * - * @param xMotor The first motor, such as an NXTMotor. - * @param xGyro The gyro accompanying xMotor. Monitors the x-axis - * @param yMotor The second motor, such as an NXTMotor. - * @param yGyro The gyro accompanying xMotor. Monitors the y-axis - * @param rollerDiameter The diameter of the motorized rollers. Usually NXT 2.0 wheels (4.32 cm) - */ - public Ballbot(EncoderMotor xMotor, Gyroscope xGyro, EncoderMotor yMotor, Gyroscope yGyro, double rollerDiameter) { - threadx = new Ballbot(xMotor, xGyro, rollerDiameter); - thready = new Ballbot(yMotor, yGyro, rollerDiameter); - - // Play warning beep sequence before balance starts - Ballbot.startBeeps(); - - // Start balance threads - threadx.start(); - try { - Thread.sleep(WAIT_TIME/2); // Stagger threads to give thread execution more space. - } catch (InterruptedException e) {} - thready.start(); - - } - - private Ballbot threadx; - private Ballbot thready; - - /** - * Number of offset samples to average when calculating gyro offset. - */ - private static final int OFFSET_SAMPLES = 100; - - /** - * This function returns a suitable initial gyro offset. It takes - * 100 gyro samples over a time of 1/2 second and averages them to - * get the offset. It also check the max and min during that time - * and if the difference is larger than one it rejects the data and - * gets another set of samples. - */ - private void getGyroOffset() { - - LCD.clear(); - LCD.drawString("NXJ Ballbot",0,1); - - LCD.drawString("Lay robot down", 0, 4); - LCD.drawString("flat to get gyro", 0, 5); - LCD.drawString("offset.", 0, 6); - - gyro.recalibrateOffset(); - } - - /** - * Warn user the Ballbot is about to start balancing. - */ - private static void startBeeps() { - LCD.clear(); - LCD.drawString("leJOS NXJ Ballbot", 0, 1); - LCD.drawString("Balance in", 0, 3); - - // Play warning beep sequence to indicate balance about to start - for (int c=8; c>=0;c--) { - LCD.drawInt(c, 5, 4); - Sound.playTone(440,100); - try { Thread.sleep(1000); - } catch (InterruptedException e) {} - } - } - - /** - * Get the data from the gyro. - * Fills the pass by reference gyroSpeed and gyroAngle based on updated information from the Gyro Sensor. - * Maintains an automatically adjusted gyro offset as well as the integrated gyro angle. - * - */ - private void updateGyroData() { - float gyroRaw; - - gyroRaw = gyro.getAngularVelocity(); - gOffset = EMAOFFSET * gyroRaw + (1-EMAOFFSET) * gOffset; - gyroSpeed = gyroRaw - gOffset; // Angular velocity (degrees/sec) - - gAngleGlobal += gyroSpeed*tInterval; - gyroAngle = gAngleGlobal; // Absolute angle (degrees) - } - - /** - * Keeps track of wheel position with both motors. - */ - private void updateMotorData() { - long mrcLeft, mrcDelta; - - // Keep track of motor position and speed - mrcLeft = my_motor.getTachoCount(); - //mrcRight = right_motor.getTachoCount(); - - // Maintain previous mrcSum so that delta can be calculated and get - // new mrcSum and Diff values - mrcSumPrev = mrcSum; - mrcSum = mrcLeft + mrcLeft; // TODO: I'm sidestepping these two lines by using mrcLeft twice - motorDiff = mrcLeft - mrcLeft; - - // mrcDetla is the change int sum of the motor encoders, update - // motorPos based on this detla - mrcDelta = mrcSum - mrcSumPrev; - motorPos += mrcDelta; - - // motorSpeed is based on the average of the last four delta's. - motorSpeed = (mrcDelta+mrcDeltaP1+mrcDeltaP2+mrcDeltaP3)/(4*tInterval); - - // Shift the latest mrcDelta into the previous three saved delta values - mrcDeltaP3 = mrcDeltaP2; - mrcDeltaP2 = mrcDeltaP1; - mrcDeltaP1 = mrcDelta; - } - - /** - * Global variables used to control the amount of power to apply to each wheel. - * Updated by the steerControl() method. - */ - private int powerLeft, powerRight; // originally local variables - - /** - * This function determines the left and right motor power that should - * be used based on the balance power and the steering control. - */ - private void steerControl(int power) { - int powerSteer; - - // Update the target motor difference based on the user steering - // control value. - motorDiffTarget += motorControlSteer * tInterval; - - // Determine the proportionate power differential to be used based - // on the difference between the target motor difference and the - // actual motor difference. - powerSteer = (int)(KSTEER * (motorDiffTarget - motorDiff)); - - // Apply the power steering value with the main power value to - // get the left and right power values. - powerLeft = power + powerSteer; - powerRight = power - powerSteer; - - // Limit the power to motor power range -100 to 100 - if (powerLeft > 100) powerLeft = 100; - if (powerLeft < -100) powerLeft = -100; - - // Limit the power to motor power range -100 to 100 - if (powerRight > 100) powerRight = 100; - if (powerRight < -100) powerRight = -100; - } - - /** - * Calculate the interval time from one iteration of the loop to the next. - * Note that first time through, cLoop is 0, and has not gone through - * the body of the loop yet. Use it to save the start time. - * After the first iteration, take the average time and convert it to - * seconds for use as interval time. - */ - private void calcInterval(long cLoop) { - if (cLoop == 0) { - // First time through, set an initial tInterval time and - // record start time - tInterval = 0.0055; - tCalcStart = System.currentTimeMillis(); - } else { - // Take average of number of times through the loop and - // use for interval time. - tInterval = (System.currentTimeMillis() - tCalcStart)/(cLoop*1000.0); - } - } - - private double gyroSpeed, gyroAngle; // originally local variables - private double motorSpeed; // originally local variable - - //--------------------------------------------------------------------- - // - // This is the main balance thread for the robot. - // - // Robot is assumed to start leaning on a wall. The first thing it - // does is take multiple samples of the gyro sensor to establish and - // initial gyro offset. - // - // After an initial gyro offset is established, the robot backs up - // against the wall until it falls forward, when it detects the - // forward fall, it start the balance loop. - // - // The main state variables are: - // gyroAngle This is the angle of the robot, it is the results of - // integrating on the gyro value. - // Units: degrees - // gyroSpeed The value from the Gyro Sensor after offset subtracted - // Units: degrees/second - // motorPos This is the motor position used for balancing. - // Note that this variable has two sources of input: - // Change in motor position based on the sum of - // MotorRotationCount of the two motors, - // and, - // forced movement based on user driving the robot. - // Units: degrees (sum of the two motors) - // motorSpeed This is the speed of the wheels of the robot based on the - // motor encoders. - // Units: degrees/second (sum of the two motors) - // - // From these state variables, the power to the motors is determined - // by this linear equation: - // power = KGYROSPEED * gyro + - // KGYROANGLE * gyroAngle + - // KPOS * motorPos + - // KSPEED * motorSpeed; - // - public void run() { - - int power; - long tMotorPosOK; - long cLoop = 0; - - LCD.clear(); - LCD.drawString("leJOS NXJ Ballbot", 0, 1); - LCD.drawString("Balancing", 0, 4); - - tMotorPosOK = System.currentTimeMillis(); - - // Reset the motors to make sure we start at a zero position - my_motor.resetTachoCount(); - //right_motor.resetTachoCount(); - - // NOTE: This balance control loop only takes 1.128 MS to execute each loop in leJOS NXJ. - while(true) { - calcInterval(cLoop++); - - updateGyroData(); - - updateMotorData(); - - // Apply the drive control value to the motor position to get robot to move. - motorPos -= motorControlDrive * tInterval; - - // This is the main balancing equation - power = (int)((KGYROSPEED * gyroSpeed + // Deg/Sec from Gyro sensor - KGYROANGLE * gyroAngle) / ratioWheel + // Deg from integral of gyro - KPOS * motorPos + // From MotorRotaionCount of both motors - KDRIVE * motorControlDrive + // To improve start/stop performance - KSPEED * motorSpeed); // Motor speed in Deg/Sec - - if (Math.abs(power) < 100) - tMotorPosOK = System.currentTimeMillis(); - - steerControl(power); // Movement control. Not used for balancing. - - // Apply the power values to the motors - // NOTE: It would be easier/faster to use MotorPort.controlMotorById(), but it needs to be public. - my_motor.setPower(Math.abs(powerLeft)); - //right_motor.setPower(Math.abs(powerRight)); - - if(powerLeft > 0) my_motor.forward(); - else my_motor.backward(); - - //if(powerRight > 0) right_motor.forward(); - //else right_motor.backward(); - - // Check if robot has fallen by detecting that motorPos is being limited - // for an extended amount of time. - if ((System.currentTimeMillis() - tMotorPosOK) > TIME_FALL_LIMIT) break; - - try {Thread.sleep(WAIT_TIME);} catch (InterruptedException e) {} - } // end of while() loop - - my_motor.flt(); - //right_motor.flt(); - - Sound.beepSequenceUp(); - LCD.drawString("Oops... I fell", 0, 4); - LCD.drawString("tInt ms:", 0, 8); - LCD.drawInt((int)tInterval*1000, 9, 8); - } // END OF BALANCING THREAD CODE - - /** - * This method does not actually - * apply direct power to the wheels. Control is filtered through to each wheel, allowing the robot to - * drive forward/backward and make turns. Higher values are faster. Negative values cause the wheel - * to rotate backwards. Values between -200 and 200 are good. If values are too high it can make the - * robot balance unstable. - * - * @param impulse_power The relative control power to the wheel. -200 to 200 are good numbers. - * - */ - - private void wheelDriver(int impulse_power) { - // Set control Drive and Steer. Both these values are in motor degree/second - motorControlDrive = (impulse_power + impulse_power) * CONTROL_SPEED / 200.0; - } - - /** - *

    Causes movement along either the xaxis or y axis. Normally power for each of these values is - * zero in order to keep the ballbot roughly stationary.

    - * - *

    This method does not actually - * apply direct power to the roller wheels. Control is filtered through to each wheel, allowing the robot to - * move. Higher values are faster. Negative values cause movement in the opposite direction. Values between -200 - * and 200 are acceptable. If values are too high it can make the robot balance unstable. Try starting with values - * around 10 or so. A ballbot needs good motors, sensors, a grippy ball/roller and be extremely symmetrical if you - * want to use higher values.

    - * - * @param x_axisPower - * @param y_axisPower - */ - public void impulseMove(int x_axisPower, int y_axisPower) { - threadx.wheelDriver(x_axisPower); - thready.wheelDriver(y_axisPower); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/CompassPilot.java b/ev3classes/src/main/java/lejos/robotics/navigation/CompassPilot.java deleted file mode 100644 index 155ac98..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/CompassPilot.java +++ /dev/null @@ -1,311 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.DirectionFinder; -import lejos.utility.Delay; - -/** - * A Pilot that keeps track of direction using a DirectionFinder. - * @deprecated This class will disappear in NXJ version 1.0. Compass should be added to a PoseProvider. - * @see lejos.robotics.localization.PoseProvider#getPose() - */ -// TODO: Note @deprecated message above, I'm not sure PoseProvider is exactly right place to point users to yet. -// Need to explain this more when we are sure how this will replace CompassPilot. - BB - -@Deprecated -public class CompassPilot extends DifferentialPilot -{ - - protected DirectionFinder compass; - protected Regulator regulator = new Regulator(); // inner regulator for thread - protected float _heading; // desired heading - protected float _estimatedHeading = 0; //estimated heading - protected boolean _traveling = false; // state variable used by regulator - protected float _distance; // set by travel() used by r egulator to stop - protected byte _direction;// direction of travel = sign of _distance - protected float _heading0 = 0;// heading when rotate immediate is called - - - /** - *returns returns true if the robot is travelling for a specific distance; - **/ - public boolean isTraveling() - { - return _traveling; - } - - /** - * Allocates a CompasPilot object, and sets the physical parameters of the NXT robot.
    - * Assumes Motor.forward() causes the robot to move forward); - * Parameters - * @param compass : a compass sensor; - * @param wheelDiameter Diameter of the tire, in any convenient units. (The diameter in mm is usually printed on the tire). - * @param trackWidth Distance between center of right tire and center of left tire, in same units as wheelDiameter - * @param leftMotor - * @param rightMotor - */ - public CompassPilot(DirectionFinder compass, float wheelDiameter, - float trackWidth, RegulatedMotor leftMotor, RegulatedMotor rightMotor) - { - this(compass, wheelDiameter, trackWidth, leftMotor, rightMotor, false); - } - - /** - * Allocates a CompasPilot object, and sets the physical parameters of the NXT robot.
    - * Assumes Motor.forward() causes the robot to move forward); - * Parameters - * @param compass : a compass sensor; - * @param wheelDiameter Diameter of the tire, in any convenient units. (The diameter in mm is usually printed on the tire). - * @param trackWidth Distance between center of right tire and center of left tire, in same units as wheelDiameter - * @param leftMotor - * @param rightMotor - * @param reverse if true of motor.forward() drives the robot backwards - */ - public CompassPilot(DirectionFinder compass, float wheelDiameter, - float trackWidth, RegulatedMotor leftMotor, RegulatedMotor rightMotor, boolean reverse) - { - super(wheelDiameter, trackWidth, leftMotor, rightMotor, reverse); - this.compass = compass; - regulator.setDaemon(true); - regulator.start(); - - } - - /** - * Return the compass - * @return the compass - */ - public DirectionFinder getCompass() - { - return compass; - } - - /** - * Returns the change in robot heading since the last call of reset() - * normalized to be within -180 and _180 degrees - */ - public float getAngleIncrement() - { - return normalize(getCompassHeading() - _heading0); - } - - /** - * Returns direction of desired robot facing - */ - public float getHeading() - { - return _estimatedHeading; - } - - /** - * Method returns the current compass heading - * @return Compass heading in degrees. - */ - public float getCompassHeading() - { - return normalize(compass.getDegreesCartesian()); - } - - /** - * sets direction of desired robot facing in degrees - */ - public void setHeading(float angle) - { - _heading = angle; - } - - /** - * Rotates the robot 360 degrees while calibrating the compass - * resets compass zero to heading at end of calibration - */ - public synchronized void calibrate() - { - setAngularSpeed(50); - compass.startCalibration(); - super.rotate(360, false); - compass.stopCalibration(); - - } - - public void resetCartesianZero() - { - compass.resetCartesianZero(); - _heading = 0; - } - - /** - * Determines the difference between actual compass direction and desired heading in degrees - * @return error (in degrees) - */ - public float getHeadingError() - { - float err = compass.getDegreesCartesian() - _heading; - // Handles the wrap-around problem: - return normalize(err); - - } - - - /** - * Moves the NXT robot a specific distance. A positive value moves it forwards and - * a negative value moves it backwards. The robot steers to maintain its compass heading. - * @param distance The positive or negative distance to move the robot, same units as _wheelDiameter - * @param immediateReturn iff true, the method returns immediately. - */ - public void travel(float distance, boolean immediateReturn) - { - movementStart(); - _type = Move.MoveType.TRAVEL; - super.travel(distance,true); - _distance = distance; - _direction = 1; - if(_distance < 0 ) _direction = -1; - _traveling = true; - if (immediateReturn) - { - return; - } - while (isMoving()) - { - Thread.yield(); // regulator will call stop when distance is reached - } - - } - - /** - * Moves the NXT robot a specific distance;
    - * A positive distance causes forward motion; negative distance moves backward. - * Robot steers to maintain its compass heading; - * @param distance of robot movement. Unit of measure for distance must be same as wheelDiameter and trackWidth - **/ - public void travel(float distance) - { - travel(distance, false); - } - - /** - * robot rotates to the specified compass heading; - * @param immediateReturn - if true, method returns immediately. - * Robot stops when specified angle is reached or when stop() is called - */ - public void rotate(float angle, boolean immediateReturn) - { - movementStart(); - _type = Move.MoveType.ROTATE; - float heading0 = getCompassHeading(); - super.rotate(angle, immediateReturn); // takes care of movement start - if (immediateReturn) return; - _heading = normalize(_heading +angle); - _traveling = false; - float error = getHeadingError(); - while (Math.abs(error) > 2) - { - super.rotate(-error, false); - error = getHeadingError(); - } - _heading0 = heading0;//needed for currect angle increment - } - - /** - * Rotates the NXT robot through a specific angle; Rotates left if angle is positive, right if negative, - * Returns when angle is reached. - * Wheels turn in opposite directions producing a zero radius turn. - * @param angle degrees. Positive angle rotates to the left (clockwise); negative to the right.
    Requires correct values for wheel diameter and track width. - */ - public void rotate(float angle) - { - rotate(angle, false); - } - - public void reset() - { - _left.resetTachoCount(); - _right.resetTachoCount(); - _heading0 = getCompassHeading(); - super.reset(); - } - - // methods required to give regulator access to Pilot superclass - protected void stopNow() - { - stop(); - } - - /** - * Stops the robot soon after the method is executed. (It takes time for the motors - * to slow to a halt) - */ - public void stop() - { - super.stop(); - _traveling = false; - while (isMoving()) - { - super.stop(); - Thread.yield(); - } - } - - - protected float normalize(float angle) - { - while (angle > 180)angle -= 360; - while (angle < -180)angle += 360; - return angle; - } - - /** - * inner class to regulate heading during travel move - * Proportional control of steering ; error is an average of heading change - * from tacho counts and from compass change - * @author Roger Glassey - */ - class Regulator extends Thread - { - - public void run() - { - while (true) - { - while (!_traveling) - { - Thread.yield(); - } - { // travel started - float toGo = _distance; // reamining trave distance - float gain = -3f * _direction; - float error = 0; - float e0 = 0; - float incr0 = 0; - _estimatedHeading = _heading0; - do // travel in progress - { - // use weighted average of heading from tacho count and compass - // weights should be based on variance of compass error and tacho count error - float incr = getAngleIncrement(); - _estimatedHeading += (incr - incr0); //change in heading from tacho counts - incr0 = incr; - _estimatedHeading = normalize( 0.5f *normalize(compass.getDegreesCartesian()) + 0.5f*_estimatedHeading); - error = normalize( _estimatedHeading - _heading); - toGo =(_distance - getMovementIncrement()); - if(Math.abs(error - e0) > 2) //only steer if large change in error > 2 deg - { - steerPrep(gain * error); - e0 = error; - } - Delay.msDelay(12); // another arbitrary constant - Thread.yield(); - } while (Math.abs(toGo) > 3 ); - // travel completed (almost) - int delta = Math.round(toGo*_leftDegPerDistance); - _left.rotate(delta,true); - delta = Math.round(toGo*_rightDegPerDistance); - _outside.rotate(delta); - while(_left.isMoving())Thread.yield(); - _traveling = false; - } - - } - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/DestinationUnreachableException.java b/ev3classes/src/main/java/lejos/robotics/navigation/DestinationUnreachableException.java deleted file mode 100644 index 98d9376..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/DestinationUnreachableException.java +++ /dev/null @@ -1,11 +0,0 @@ -package lejos.robotics.navigation; - -/** - * Exception thrown by path finders when the destination cannot be reached - * - * @author nxj team - * - */ -public class DestinationUnreachableException extends Exception { - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/DifferentialPilot.java b/ev3classes/src/main/java/lejos/robotics/navigation/DifferentialPilot.java deleted file mode 100644 index cd3117a..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/DifferentialPilot.java +++ /dev/null @@ -1,1238 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; - -import java.util.ArrayList; - -/** - * The DifferentialPilot class is a software abstraction of the Pilot mechanism - * of a NXT robot. It contains methods to control robot movements: travel - * forward or backward in a straight line or a circular path or rotate to a new - * direction.
    - * This class will only work with two independently controlled motors to steer - * differentially, so it can rotate within its own footprint (i.e. turn on one - * spot). It registers as a {@link lejos.robotics.RegulatedMotorListener} with - * each of its motors. An object of this class assumes that it has exclusive - * control of its motors. If any other object makes calls to its motors, the - * results are unpredictable.
    - * This class can be used with robots that have reversed motor design: the robot - * moves in the direction opposite to the the direction of motor rotation. .
    - * It automatically updates a - * {@link lejos.robotics.localization.OdometryPoseProvider} which has called the - * addMoveListener method on this object.
    - * Some methods optionally return immediately so the thread that called it can - * do things while the robot is moving, such as monitor sensors and call - * {@link #stop()}.
    - * Handling stalls: If a stall is detected, isStalled() returns - * - * true , isMoving() returns false, - * moveStopped() - * is called, and, if a blocking method is executing, that method exits. - * The units of measure for travel distance, speed and acceleration are the - * units used in specifying the wheel diameter and track width in the - * constructor.
    - * In all the methods that cause the robot to change its heading (the angle - * relative to the X axis in which the robot is facing) the angle parameter - * specifies the change in heading. A positive angle causes a turn to the left - * (anti-clockwise) to increase the heading, and a negative angle causes a turn - * to the right (clockwise).
    - * Example of use of come common methods: - *

    - *

    - * DifferentialPilot pilot = new DifferentialPilot(2.1f, 4.4f, Motor.A, Motor.C, true);  // parameters in inches
    - * pilot.setRobotSpeed(30);  // cm per second
    - * pilot.travel(50);         // cm
    - * pilot.rotate(-90);        // degree clockwise
    - * pilot.travel(-50,true);  //  move backward for 50 cm
    - * while(pilot.isMoving())Thread.yield();
    - * pilot.rotate(-90);
    - * pilot.rotateTo(270);
    - * pilot.steer(-50,180,true); // turn 180 degrees to the right
    - * waitComplete();            // returns when previous method is complete
    - * pilot.steer(100);          // turns with left wheel stationary
    - * Delay.msDelay(1000;
    - * pilot.stop();
    - * 
    - *

    - *

    - * Note: A DifferentialPilot robot can simulate a SteeringPilot robot by calling - * DifferentialPilot.setMinRadius() and setting the value to something greater - * than zero (perhaps 15 cm). - *

    - * @deprecated use {@link MovePilot} instead. - **/ -@Deprecated -public class DifferentialPilot implements LineFollowingMoveController { - /** - * Allocates a DifferentialPilot object, and sets the physical parameters of - * the NXT robot.
    - * Assumes Motor.forward() causes the robot to move forward. - * - * @param wheelDiameter - * Diameter of the tire, in any convenient units (diameter in mm - * is usually printed on the tire). - * @param trackWidth - * Distance between center of right tire and center of left tire, - * in same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - */ - public DifferentialPilot(final double wheelDiameter, - final double trackWidth, final RegulatedMotor leftMotor, - final RegulatedMotor rightMotor) { - this(wheelDiameter, trackWidth, leftMotor, rightMotor, false); - } - - /** - * Allocates a DifferentialPilot object, and sets the physical parameters of - * the NXT robot.
    - * - * @param wheelDiameter - * Diameter of the tire, in any convenient units (diameter in mm - * is usually printed on the tire). - * @param trackWidth - * Distance between center of right tire and center of left tire, - * in same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - * @param reverse - * If true, the NXT robot moves forward when the motors are - * running backward. - */ - public DifferentialPilot(final double wheelDiameter, - final double trackWidth, final RegulatedMotor leftMotor, - final RegulatedMotor rightMotor, final boolean reverse) { - this(wheelDiameter, wheelDiameter, trackWidth, leftMotor, rightMotor, - reverse); - } - - /** - * Allocates a DifferentialPilot object, and sets the physical parameters of - * the NXT robot.
    - * - * @param leftWheelDiameter - * Diameter of the left wheel, in any convenient units (diameter - * in mm is usually printed on the tire). - * @param rightWheelDiameter - * Diameter of the right wheel. You can actually fit - * intentionally wheels with different size to your robot. If you - * fitted wheels with the same size, but your robot is not going - * straight, try swapping the wheels and see if it deviates into - * the other direction. That would indicate a small difference in - * wheel size. Adjust wheel size accordingly. The minimum change - * in wheel size which will actually have an effect is given by - * minChange = A*wheelDiameter*wheelDiameter/(1-(A*wheelDiameter) - * where A = PI/(moveSpeed*360). Thus for a moveSpeed of 25 - * cm/second and a wheelDiameter of 5,5 cm the minChange is about - * 0,01058 cm. The reason for this is, that different while sizes - * will result in different motor speed. And that is given as an - * integer in degree per second. - * @param trackWidth - * Distance between center of right tire and center of left tire, - * in same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - * @param reverse - * If true, the NXT robot moves forward when the motors are - * running backward. - */ - public DifferentialPilot(final double leftWheelDiameter, - final double rightWheelDiameter, final double trackWidth, - final RegulatedMotor leftMotor, final RegulatedMotor rightMotor, - final boolean reverse) { - _left = leftMotor; - _leftWheelDiameter = (float) leftWheelDiameter; - _leftTurnRatio = (float) (trackWidth / leftWheelDiameter); - _leftDegPerDistance = (float) (360 / (Math.PI * leftWheelDiameter)); - // right - _right = rightMotor; - _rightWheelDiameter = (float) rightWheelDiameter; - _rightTurnRatio = (float) (trackWidth / rightWheelDiameter); - _rightDegPerDistance = (float) (360 / (Math.PI * rightWheelDiameter)); - // both - _trackWidth = (float) trackWidth; - _parity = (byte) (reverse ? -1 : 1); - setLinearSpeed(.8f * getMaxLinearSpeed()); - setAngularSpeed(.8f * getMaxRotateSpeed()); - setLinearAcceleration((int) (_robotTravelSpeed * 4)); - _monitor = new Monitor(); - _monitor.start(); - _left.synchronizeWith(new RegulatedMotor[]{_right}); - } - - /** - * Returns the tachoCount of the left motor - * - * @return tachoCount of left motor. Positive value means motor has moved - * the robot forward. - */ - private int getLeftCount() { - return _parity * _left.getTachoCount(); - } - - /** - * Returns the tachoCount of the right motor - * - * @return tachoCount of the right motor. Positive value means motor has - * moved the robot forward. - */ - private int getRightCount() { - return _parity * _right.getTachoCount(); - } - - /* - * public int getRightActualSpeed() { return _right.getRotationSpeed(); } - */ - private void setSpeed(final int leftSpeed, final int rightSpeed) { - _left.startSynchronization(); - _left.setSpeed(leftSpeed); - _right.setSpeed(rightSpeed); - _left.endSynchronization(); - } - - /** - * set travel speed in wheel diameter units per second - * - * @param travelSpeed - * : speed in distance (wheel diameter)units/sec - */ - public void setLinearSpeed(final double travelSpeed) { - if (!isMoving()) { - _robotTravelSpeed = (float) travelSpeed; - setSpeed((int) Math.round(travelSpeed * _leftDegPerDistance), - (int) Math.round(travelSpeed * _rightDegPerDistance)); - } else { - float speedRatio = (float) travelSpeed / _robotTravelSpeed; - _left.startSynchronization(); - _left.setSpeed((int) Math.round(_left.getSpeed() * speedRatio)); - _right.setSpeed((int) Math.round(_right.getSpeed() * speedRatio)); - _left.endSynchronization(); - _robotTravelSpeed = (float) travelSpeed; - } - } - - public double getLinearSpeed() { - return _robotTravelSpeed; - } - - @Override - public void setLinearAcceleration(double acceleration) { - _acceleration = (int)acceleration; - setMotorAccel(_acceleration); - } - - @Override - public double getLinearAcceleration() { - return _acceleration; - } - - /** - * helper method for setAcceleration and quickStop - * - * @param acceleration - */ - private void setMotorAccel(int acceleration) { - _left.startSynchronization(); - _left.setAcceleration((int) (acceleration * _leftDegPerDistance)); - _right.setAcceleration((int) (acceleration * _rightDegPerDistance)); - _left.endSynchronization(); - } - - public double getMaxLinearSpeed() { - return Math.min(_left.getMaxSpeed(), _right.getMaxSpeed()) - / Math.max(_leftDegPerDistance, _rightDegPerDistance); - // max degree/second divided by degree/unit = unit/second - } - - /** - * sets the rotation speed of the vehicle, degrees per second - * - * @param rotateSpeed - */ - public void setAngularSpeed(double rotateSpeed) { - _robotRotateSpeed = (float) rotateSpeed; - setSpeed((int) Math.round(rotateSpeed * _leftTurnRatio), - (int) Math.round(rotateSpeed * _rightTurnRatio)); - } - - public double getAngularSpeed() { - return _robotRotateSpeed; - } - - public float getMaxRotateSpeed() { - return Math.min(_left.getMaxSpeed(), _right.getMaxSpeed()) - / Math.max(_leftTurnRatio, _rightTurnRatio); - // max degree/second divided by degree/unit = unit/second - } - - public double getMaxAngularSpeed() { - return getMaxRotateSpeed(); - } - - /** - * Starts the NXT robot moving forward. - */ - public void forward() { - waitForActiveMove(); - _type = Move.MoveType.TRAVEL; - _angle = 0; - _distance = Double.POSITIVE_INFINITY; - _leftDirection = 1; - _rightDirection = 1; - movementStart(); - setSpeed(Math.round(_robotTravelSpeed * _leftDegPerDistance), - Math.round(_robotTravelSpeed * _rightDegPerDistance)); - if (_parity == 1) { - fwd(); - } else { - bak(); - } - } - - /** - * Starts the NXT robot moving backward. - */ - public void backward() { - waitForActiveMove(); - _type = Move.MoveType.TRAVEL; - _distance = Double.NEGATIVE_INFINITY; - _angle = 0; - _leftDirection = -1; - _rightDirection = -1; - movementStart(); - setSpeed(Math.round(_robotTravelSpeed * _leftDegPerDistance), - Math.round(_robotTravelSpeed * _rightDegPerDistance)); - if (_parity == 1) { - bak(); - } else { - fwd(); - } - } - - /** - * Motors backward. This is called by forward() and backward(), depending on - * parity. - */ - private void bak() { - _left.startSynchronization(); - _left.backward(); - _right.backward(); - _left.endSynchronization(); - movementActive(); - } - - /** - * Motors forward. This is called by forward() and backward() depending on - * parity. - */ - private void fwd() { - _left.startSynchronization(); - _left.forward(); - _right.forward(); - _left.endSynchronization(); - movementActive(); - } - - public void rotateLeft() { - waitForActiveMove(); - _type = Move.MoveType.ROTATE; - _distance = 0; - _angle = Double.POSITIVE_INFINITY; - movementStart(); - _left.startSynchronization(); - setMotorAccel(_acceleration); - if (_parity > 0) { - _right.forward(); - _left.backward(); - } else { - _left.forward(); - _right.backward(); - } - _left.endSynchronization(); - movementActive(); - } - - public void rotateRight() { - waitForActiveMove(); - _type = Move.MoveType.ROTATE; - _distance = 0; - _angle = Double.NEGATIVE_INFINITY; - movementStart(); - _left.startSynchronization(); - setMotorAccel(_acceleration); - if (_parity > 0) { - _left.forward(); - _right.backward(); - } else { - _right.forward(); - _left.backward(); - } - _left.endSynchronization(); - } - - - /** - * Rotates the NXT robot through a specific angle. Returns when angle is - * reached. Wheels turn in opposite directions producing a zero radius turn.
    - * Note: Requires correct values for wheel diameter and track width. calls - * rotate(angle,false) - * - * @param angle - * The wanted angle of rotation in degrees. Positive angle rotate - * left (anti-clockwise), negative right. - */ - public void rotate(final double angle) { - rotate(angle, false); - } - - /** - * Rotates the NXT robot through a specific angle. Returns when angle is - * reached. Wheels turn in opposite directions producing a zero radius turn.
    - * Note: Requires correct values for wheel diameter and track width. Side - * effect: inform listeners - * - * @param angle - * The wanted angle of rotation in degrees. Positive angle rotate - * left (anti-clockwise), negative right. - * @param immediateReturn - * If true this method returns immediately. - */ - public void rotate(final double angle, final boolean immediateReturn) { - waitForActiveMove(); - _type = Move.MoveType.ROTATE; - _distance = 0; - _angle = angle; - int rotateAngleLeft = _parity * (int) (angle * _leftTurnRatio); - int rotateAngleRight = _parity * (int) (angle * _rightTurnRatio); - movementStart(); - _left.startSynchronization(); - setMotorAccel(_acceleration); - setSpeed(Math.round(_robotRotateSpeed * _leftTurnRatio), - Math.round(_robotRotateSpeed * _rightTurnRatio)); - _left.rotate(-rotateAngleLeft, true); - _leftDirection = (byte) Math.signum(-rotateAngleLeft); - _right.rotate(rotateAngleRight, true); - _rightDirection = (byte) Math.signum(rotateAngleRight); - _left.endSynchronization(); - movementActive(); - if (!immediateReturn) - waitComplete(); - } - - /** - * Stops the NXT robot. side effect: inform listeners of end of movement - */ - public void stop() { - -// System.out.println("stop called"); - _left.startSynchronization(); - _left.stop(true); - _right.stop(true); - _left.endSynchronization(); - waitComplete(); - synchronized(_monitor) - { - _monitor.notifyAll(); - } - setMotorAccel(_acceleration); - - } - - /** - * Stops the robot almost immediately. Use this method if the normal - * {@link #stop()} is too slow; - */ - public void quickStop() { - setMotorAccel(_quickAcceleration); - stop(); - setMotorAccel(_acceleration); - } - - /** - * Moves the NXT robot a specific distance in an (hopefully) straight line.
    - * A positive distance causes forward motion, a negative distance moves - * backward. If a drift correction has been specified in the constructor it - * will be applied to the left motor. calls travel(distance, false) - * - * @param distance - * The distance to move. Unit of measure for distance must be - * same as wheelDiameter and trackWidth. - **/ - public void travel(final double distance) { - travel(distance, false); - } - - - /** - * Moves the NXT robot a specific distance in an (hopefully) straight line.
    - * A positive distance causes forward motion, a negative distance moves - * backward. If a drift correction has been specified in the constructor it - * will be applied to the left motor. - * - * @param distance - * The distance to move. Unit of measure for distance must be - * same as wheelDiameter and trackWidth. - * @param immediateReturn - * If true this method returns immediately. - */ - public void travel(final double distance, final boolean immediateReturn) { - waitForActiveMove(); - _type = Move.MoveType.TRAVEL; - _distance = distance; - _angle = 0; - movementStart(); - setMotorAccel(_acceleration); - _leftDirection = 1; - _rightDirection = 1; - if (distance < 0) { - _leftDirection = -1; - _rightDirection = -1; - } - - if (distance == Double.POSITIVE_INFINITY) { - forward(); - return; - } - if ((distance == Double.NEGATIVE_INFINITY)) { - backward(); - return; - } - setSpeed(Math.round(_robotTravelSpeed * _leftDegPerDistance), - Math.round(_robotTravelSpeed * _rightDegPerDistance)); - _left.startSynchronization(); - _left.rotate((int) (_parity * distance * _leftDegPerDistance), true); - _right.rotate((int) (_parity * distance * _rightDegPerDistance), true); - _left.endSynchronization(); - movementActive(); - if (!immediateReturn) - waitComplete(); - } - - public void arcForward(final double radius) { - waitForActiveMove(); - _type = Move.MoveType.ARC; - if (radius > 0) { - _angle = Double.POSITIVE_INFINITY; - _distance = Double.POSITIVE_INFINITY; - } else { - _angle = Double.NEGATIVE_INFINITY; - _distance = Double.NEGATIVE_INFINITY; - } - movementStart(); - double turnRate = turnRate(radius); - steerPrep(turnRate); // sets motor speeds - _left.startSynchronization(); - if (_parity > 0) - _outside.forward(); - else - _outside.backward(); - if (_parity * _steerRatio > 0) - _inside.forward(); - else - _inside.backward(); - _left.endSynchronization(); - movementActive(); - } - - public void arcBackward(final double radius) { - waitForActiveMove(); - _type = Move.MoveType.ARC; - if (radius < 0) { - _angle = Double.POSITIVE_INFINITY; - _distance = Double.NEGATIVE_INFINITY; - } else { - _angle = Double.NEGATIVE_INFINITY; - _distance = Double.POSITIVE_INFINITY; - } - movementStart(); - double turnRate = turnRate(radius); - steerPrep(turnRate);// sets motor speeds - _left.startSynchronization(); - if (_parity > 0) - _outside.backward(); - else - _outside.forward(); - if (_parity * _steerRatio > 0) - _inside.backward(); - else - _inside.forward(); - _left.endSynchronization(); - movementActive(); - } - - public void arc(final double radius, final double angle) { - arc(radius, angle, false); - } - - public void arc(final double radius, final double angle, - final boolean immediateReturn) { - if (radius == Double.POSITIVE_INFINITY - || radius == Double.NEGATIVE_INFINITY) { - forward(); - return; - } - steer(turnRate(radius), angle, immediateReturn);// type and move started - // called by steer() - } - - public void travelArc(double radius, double distance) { - travelArc(radius, distance, false); - } - - public void travelArc(double radius, double distance, - boolean immediateReturn) { - waitForActiveMove(); - if (radius == Double.POSITIVE_INFINITY - || radius == Double.NEGATIVE_INFINITY) { - travel(distance, immediateReturn); - return; - } - if (radius == 0) { - throw new IllegalArgumentException("Zero arc radius"); - } - double angle = (distance * 180) / ((float) Math.PI * radius); - arc(radius, angle, immediateReturn); - } - - /** - * Calculates the turn rate corresponding to the turn radius;
    - * use as the parameter for steer() negative argument means center of turn - * is on right, so angle of turn is negative - * - * @param radius - * @return turnRate to be used in steer() - */ - private double turnRate(final double radius) { - int direction; - double radiusToUse; - if (radius < 0) { - direction = -1; - radiusToUse = -radius; - } else { - direction = 1; - radiusToUse = radius; - } - double ratio = (2 * radiusToUse - _trackWidth) - / (2 * radiusToUse + _trackWidth); - return (direction * 100 * (1 - ratio)); - } - - /** - * Returns the radius of the turn made by steer(turnRate) Used in for - * planned distance at start of arc and steer moves. - * - * @param turnRate - * @return radius of the turn. - */ - private double radius(double turnRate) { - double radius = 100 * _trackWidth / turnRate; - if (turnRate > 0) - radius -= _trackWidth / 2; - else - radius += _trackWidth / 2; - return radius; - } - - /** - * Starts the robot moving forward along a curved path. This method is - * similar to the {@link #arcForward(double radius )} method except it uses - * the turnRate parameter do determine the curvature of the - * path and therefore has the ability to drive straight. This makes it - * useful for line following applications. - *

    - * The turnRate specifies the sharpness of the turn. Use values - * between -200 and +200.
    - * A positive value means that center of the turn is on the left. If the - * robot is traveling toward the top of the page the arc looks like this: - * ).
    - * A negative value means that center of the turn is on the right so the arc - * looks this: (.
    - * . In this class, this parameter determines the ratio of inner wheel speed - * to outer wheel speed as a percent.
    - * Formula: ratio = 100 - abs(turnRate).
    - * When the ratio is negative, the outer and inner wheels rotate in opposite - * directions. Examples of how the formula works: - *

      - *
    • steer(0) -> inner and outer wheels turn at the same - * speed, travel straight - *
    • steer(25) -> the inner wheel turns at 75% of the speed - * of the outer wheel, turn left - *
    • steer(100) -> the inner wheel stops and the outer wheel - * is at 100 percent, turn left - *
    • steer(200) -> the inner wheel turns at the same speed as - * the outer wheel - a zero radius turn. - *
    - *

    - * Note: If you have specified a drift correction in the constructor it will - * not be applied in this method. - * - * @param turnRate - * If positive, the left side of the robot is on the inside of - * the turn. If negative, the left side is on the outside. - */ - public void steer(double turnRate) { - waitForActiveMove(); - _type = Move.MoveType.ARC; - if (turnRate > 0) { - _angle = Double.POSITIVE_INFINITY; - _distance = Double.POSITIVE_INFINITY; - } else { - _angle = Double.NEGATIVE_INFINITY; - _distance = Double.NEGATIVE_INFINITY; - } - steerPrep(turnRate); - if (turnRate == 0) { - forward(); - return; - } - movementStart(); - _left.startSynchronization(); - if (_parity > 0) - _outside.forward(); - else - _outside.backward(); - if (_parity * _steerRatio > 0) - _inside.forward(); - else - _inside.backward(); - _left.endSynchronization(); - movementActive(); - } - - /** - * Starts the robot moving backward along a curved path. This method is - * essentially the same as {@link #steer(double)} except that the robot - * moves backward instead of forward. - * - * @param turnRate - */ - public void steerBackward(final double turnRate) { - waitForActiveMove(); - if (turnRate == 0) { - if (_parity < 0) - forward(); - else - backward(); - return; - } - steerPrep(turnRate); - movementStart(); - _left.startSynchronization(); - if (_parity > 0) - _outside.backward(); - else - _outside.forward(); - _type = Move.MoveType.ARC; - if (turnRate < 0) { - _angle = Double.POSITIVE_INFINITY; - _distance = Double.NEGATIVE_INFINITY; - } else { - _angle = Double.NEGATIVE_INFINITY; - _distance = Double.POSITIVE_INFINITY; - } - if (_parity * _steerRatio > 0) - _inside.backward(); - else - _inside.forward(); - _left.endSynchronization(); - movementActive(); - } - - /** - * Moves the robot along a curved path through a specified turn angle. This - * method is similar to the {@link #arc(double radius , double angle)} - * method except it uses a ratio of motor speeds to determine the curvature - * of the path and therefore has the ability to drive straight. This makes - * it useful for line following applications. This method does not return - * until the robot has completed moving angle degrees along the - * arc.
    - * The turnRate specifies the sharpness of the turn. Use values - * between -200 and +200.
    - * For details about how this parameter works.See - * {@link #steer(double turnRate) } - *

    - * The robot will stop when its heading has changed by the amount of the - * angle parameter.
    - * If angle is positive, the robot will move in the direction - * that increases its heading (it turns left).
    - * If angle is negative, the robot will move in the directin - * that decreases its heading (turns right).
    - * If angle is zero, the robot will not move and the method - * returns immediately. - *

    - * The sign of the turn rate and the sign of the angle together determine if - * the robot will move forward or backward. Assuming the robot is heading - * toward the top of the page. Then a positive turn rate means the arc looks - * like this: ) . If the angle is positive, the robot moves forward - * to increase its heading angle. If negative, it moves backward to decrease - * the heading.
    - * But if the turn rate is negative, the arc looks like this: ( .So - * a positive angle (increase in heading) means the robot moves backwards, - * while a negative angle means the robot moves forward to decrease its - * heading. - * - *

    - * Note: If you have specified a drift correction in the constructor it will - * not be applied in this method. - * - * @param turnRate - * If positive, the left side of the robot is on the inside of - * the turn. If negative, the left side is on the outside. - * @param angle - * The angle through which the robot will rotate. If negative, - * the robot will move in the directin that decreases its - * heading. - */ - public void steer(final double turnRate, double angle) { - steer(turnRate, angle, false); - } - - /** - * Moves the robot along a curved path for a specified angle of rotation. - * This method is similar to the - * {@link #arc(double radius, double angle, boolean immediateReturn)} method - * except it uses the turnRate() parameter to determine the - * curvature of the path and therefore has the ability to drive straight. - * This makes it useful for line following applications. This method has the - * ability to return immediately by using the immediateReturn - * parameter set to true. - * - *

    - * The turnRate specifies the sharpness of the turn. Use values - * between -200 and +200.
    - * For details about how this parameter works, see - * {@link #steer(double turnRate) } - *

    - * The robot will stop when its heading has changed by the amount of the - * angle parameter.
    - * If angle is positive, the robot will move in the direction - * that increases its heading (it turns left).
    - * If angle is negative, the robot will move in the direction - * that decreases its heading (turns right).
    - * If angle is zero, the robot will not move and the method - * returns immediately.
    - * For more details about this parameter, see - * {@link #steer(double turnRate, double angle)} - *

    - * Note: If you have specified a drift correction in the constructor it will - * not be applied in this method. - * - * @param turnRate - * If positive, the left side of the robot is on the inside of - * the turn. If negative, the left side is on the outside. - * @param angle - * The angle through which the robot will rotate. If negative, - * robot traces the turning circle backwards. - * @param immediateReturn - * If immediateReturn is true then the method returns - * immediately. - */ - public void steer(final double turnRate, final double angle, - final boolean immediateReturn) { - waitForActiveMove(); - if (angle == 0) { - return; - } - movementStart(); - if (turnRate == 0) { - forward(); - return; - } - _type = Move.MoveType.ARC; - _angle = angle; - _distance = 2 * Math.toRadians(angle) * radius(turnRate); - steerPrep(turnRate); - int side = (int) Math.signum(turnRate); - int rotAngle = (int) (angle * _trackWidth * 2 / (_leftWheelDiameter * (1 - _steerRatio))); - _left.startSynchronization(); - _inside.rotate((int) (_parity * side * rotAngle * _steerRatio), true); - _outside.rotate(_parity * side * rotAngle, immediateReturn); - _left.endSynchronization(); - movementActive(); - setMotorAccel(_acceleration); - if (immediateReturn) { - return; - } - waitComplete(); - _inside.setSpeed(_outside.getSpeed()); - } - - /** - * helper method used by steer(float) and steer(float,float,boolean) sets - * _outsideSpeed, _insideSpeed, _steerRatio set motor acceleration to help - * continuous steer and arc moves - * - * @param turnRate - * . - */ - void steerPrep(final double turnRate) { - double rate = turnRate; - if (rate < -200) - rate = -200; - if (rate > 200) - rate = 200; - float insideDegPerDist = _leftDegPerDistance; - float outsideDegPerDist = _rightDegPerDistance; - byte insideDirection = _leftDirection; - byte outsideDirection = _rightDirection; - - if (turnRate < 0) { - _inside = _right; - insideDegPerDist = _rightDegPerDistance; - insideDirection = _rightDirection; - _outside = _left; - outsideDegPerDist = _leftDegPerDistance; - outsideDirection = _leftDirection; - rate = -rate; - } else { - _inside = _left; - _outside = _right; - } - _leftDirection = 1; - _rightDirection = 1; - _steerRatio = (float) (1 - rate / 100.0); - float outsideSpeed = _robotTravelSpeed * outsideDegPerDist; - float insideSpeed = _robotTravelSpeed * insideDegPerDist * _steerRatio; - float inSpeed0 = 0; - if (_inside.isMoving()) - inSpeed0 = _inside.getSpeed() * insideDirection; - float insideDV = Math.abs(insideSpeed - inSpeed0); - float outSpeed0 = 0; - if (_outside.isMoving()) - outSpeed0 = _outside.getSpeed() * outsideDirection; - float outsideDV = Math.abs(outsideSpeed - outSpeed0); - _outside.setSpeed((int) outsideSpeed); - _inside.setSpeed((int) insideSpeed); - if (insideDV < outsideDV) { - float acc = _acceleration * outsideDegPerDist; - _outside.setAcceleration((int) acc); - float ratio = insideDV / outsideDV; - if (ratio < .1) - _inside.setAcceleration((int) acc); - else - _inside.setAcceleration((int) (acc * ratio)); - } else { // outsideDV < insideDV - float acc = _acceleration * insideDegPerDist; - _inside.setAcceleration((int) acc); - float ratio = outsideDV / insideDV; - if (ratio < .1) - _outside.setAcceleration((int) acc); - else - _outside.setAcceleration((int) (acc * ratio)); - } - if (_steerRatio < 0) { - if (_inside == _left) - _leftDirection = -1; - else - _rightDirection = -1; - } - } - - - /** - * called at start of a movement to inform the listeners that a movement has - * started. Must be called before the motors start to move to capture the correct - * positional information - */ - protected void movementStart() { - Move move = new Move(_type, getMovementIncrement(), - getAngleIncrement(), _robotTravelSpeed, _robotRotateSpeed, - isMoving()); - reset(); - for (MoveListener ml : _listeners) - ml.moveStarted(move, this); - reset(); - } - - /** - * Called to indicate that the motors are now running and should be monitored for movement. Must - * be called after the motors are started. - */ - protected void movementActive() - { - synchronized(_monitor) - { - _moveActive = true; - _monitor.notifyAll(); - } - } - - /** - * called by Arc() ,travel(),rotate(),stop() rotationStopped() calls - * moveStopped on listener - */ - private void movementStop() { - Move move; - move = new Move(_type, getMovementIncrement(), - getAngleIncrement(), _robotTravelSpeed, _robotRotateSpeed, - isMoving()); - for (MoveListener ml : _listeners) - ml.moveStopped(move, this); - synchronized(_monitor) - { - _moveActive = false; - _monitor.notifyAll(); - } - } - - /** - * @return true if the NXT robot is moving. - **/ - public boolean isMoving() { - return _left.isMoving() || _right.isMoving(); - } - - /** - * wait for the current operation on both motors to complete - */ - private synchronized void waitComplete() { - while (isMoving()) { - _left.waitComplete(); - _right.waitComplete(); - } - } - - private void waitForActiveMove() { - synchronized(_monitor) - { - if (_moveActive) - { - if (isMoving()) - stop(); - while (_moveActive) - try - { - _monitor.wait(); - } catch (InterruptedException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - - public boolean isStalled() { - return _left.isStalled() || _right.isStalled(); - } - - /** - * Resets tacho count for both motors. - **/ - public void reset() { - _leftTC = getLeftCount(); - _rightTC = getRightCount(); - } - - /** - * Set the radius of the minimum turning circle. Note: A DifferentialPilot - * robot can simulate a SteeringPilot robot by calling - * DifferentialPilot.setMinRadius() and setting the value to something - * greater than zero (example: 15 cm). - * - * @param radius - * in degrees - */ - public void setMinRadius(double radius) { - _turnRadius = (float) radius; - } - - public double getMinRadius() { - return _turnRadius; - } - - /** - * - * @return The move distance since it last started moving - */ - public float getMovementIncrement() { - float left = (getLeftCount() - _leftTC) / _leftDegPerDistance; - float right = (getRightCount() - _rightTC) / _rightDegPerDistance; - return /* _parity * */(left + right) / 2.0f; - } - - /** - * - * @return The angle rotated since rotation began. - * - */ - public float getAngleIncrement() { - return /* _parity * */(((getRightCount() - _rightTC) / _rightTurnRatio) - ((getLeftCount() - _leftTC) / _leftTurnRatio)) / 2.0f; - } - - public void addMoveListener(MoveListener m) { - _listeners.add(m); - } - - public Move getMovement() { - return new Move(_type, getMovementIncrement(), getAngleIncrement(), - isMoving()); - } - - /** - * Get the turn rate for arc and steer commands - * - * @return the turn rate - */ - public double getTurnRate() { - return _robotRotateSpeed; - } - - private class Monitor extends Thread { - public boolean more = true; - public Monitor() - { - // don't make VM hang for us! - setDaemon(true); - } - - public synchronized void run() { - while (more) { - if (_moveActive) - { - if (isStalled()) - DifferentialPilot.this.stop(); - if (!isMoving()) - movementStop(); - } - // wait for an event - try - { - wait(_moveActive ? 1 : 100); - } catch (InterruptedException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } - - private float _turnRadius = 0; - /** - * Left motor.. - */ - protected final RegulatedMotor _left; - /** - * Right motor. - */ - protected final RegulatedMotor _right; - /** - * The motor at the inside of the turn. set by steer(turnRate) used by other - * steer methodsl - */ - private RegulatedMotor _inside; - /** - * The motor at the outside of the turn. set by steer(turnRate) used by - * other steer methodsl - */ - protected RegulatedMotor _outside; - /** - * ratio of inside/outside motor speeds set by steer(turnRate) used by other - * steer methods; - */ - private float _steerRatio; - /** - * Left motor degrees per unit of travel. - */ - protected final float _leftDegPerDistance; - /** - * Right motor degrees per unit of travel. - */ - protected final float _rightDegPerDistance; - /** - * Left motor revolutions for 360 degree rotation of robot (motors running - * in opposite directions). Calculated from wheel diameter and track width. - * Used by rotate() and steer() methods. - **/ - private final float _leftTurnRatio; - /** - * Right motor revolutions for 360 degree rotation of robot (motors running - * in opposite directions). Calculated from wheel diameter and track width. - * Used by rotate() and steer() methods. - **/ - private final float _rightTurnRatio; - /** - * Speed of robot for moving in wheel diameter units per seconds. Set by - * setSpeed(), setTravelSpeed() - */ - private float _robotTravelSpeed; - /** - * Speed of robot for turning in degree per seconds. - */ - private float _robotRotateSpeed; - /** - * Motor rotation forward makes robot move forward if parity == 1. - */ - private byte _parity; - /** - * Distance between wheels. Used in steer() and rotate(). - */ - private final float _trackWidth; - /** - * Diameter of left wheel. - */ - private final float _leftWheelDiameter; - /** - * Diameter of right wheel. - */ - private final float _rightWheelDiameter; - private int _leftTC; // left tacho count - private int _rightTC; // right tacho count - private ArrayList _listeners = new ArrayList(); - /** - */ - protected Move.MoveType _type; - /** - * Distance about to travel - used by movementStarted - */ - private double _distance; - /** - * Angle about to turn - used by movementStopped - */ - private double _angle; - /** - * used by travel and rotate methods, and stop() - */ - private int _acceleration; - private int _quickAcceleration = 9999; // used for quick stop. - /** - * direction of rotation of left motor +1 or -1 - */ - private byte _leftDirection = 1; - /** - * direction of rotation of right motor +1 or -1 - */ - private byte _rightDirection; - - /** - * The monitor thread - */ - private Monitor _monitor; - /** - * set by rotatsionStopped() used by Monitor thread to call - * movementStopped() - */ - - private boolean _moveActive; - @Override - public void setAngularAcceleration(double acceleration) { - // TODO Pilot does not take angular acceleration into account. - // The method serves as a placeholder to satisfy the interface. - - } - - @Override - public double getAngularAcceleration() { - // TODO see setAngularAcceleration - return 0; - } - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/LineFollowingMoveController.java b/ev3classes/src/main/java/lejos/robotics/navigation/LineFollowingMoveController.java deleted file mode 100644 index 4547f62..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/LineFollowingMoveController.java +++ /dev/null @@ -1,78 +0,0 @@ -package lejos.robotics.navigation; - -public interface LineFollowingMoveController extends ArcRotateMoveController { - /** Moves the robot forward while making a curve specified by turnRate.

    - * - * This move is suited for line following as it executes immediately without stopping the move that the robot is currently executing. - * It is also non blocking, control goes back to the main program right way. - *

    - * The turnRate specifies the sharpness of the turn. Use values - * between -200 and +200.
    - * A positive value means that center of the turn is on the left. If the - * robot is traveling toward the top of the page the arc looks like this: - * ).
    - * A negative value means that center of the turn is on the right so the arc - * looks this: (.
    - * . In this class, this parameter determines the ratio of inner wheel speed - * to outer wheel speed as a percent.
    - * Formula: ratio = 100 - abs(turnRate).
    - * When the ratio is negative, the outer and inner wheels rotate in opposite - * directions. Examples of how the formula works: - *

      - *
    • steer(0) -> inner and outer wheels turn at the same - * speed, travel straight - *
    • steer(25) -> the inner wheel turns at 75% of the speed - * of the outer wheel, turn left - *
    • steer(100) -> the inner wheel stops and the outer wheel - * is at 100 percent, turn left - *
    • steer(200) -> the inner wheel turns at the same speed as - * the outer wheel - a zero radius turn. - *
    - *

    - * Note: If you have specified a drift correction in the constructor it will - * not be applied in this method. - * - * @param turnRate - * If positive, the left side of the robot is on the inside of - * the turn. If negative, the left side is on the outside. - */ - public void steer(double turnRate); - - /** Moves the robot backward while making a curve specified by turnRate.

    - * - * This move is suited for line following as it executes immediately without stopping the move that the robot is currently executing. - * It is also non blocking, control goes back to the main program right way. - *

    - * The turnRate specifies the sharpness of the turn. Use values - * between -200 and +200.
    - * A positive value means that center of the turn is on the left. If the - * robot is traveling toward the top of the page the arc looks like this: - * ).
    - * A negative value means that center of the turn is on the right so the arc - * looks this: (.
    - * . In this class, this parameter determines the ratio of inner wheel speed - * to outer wheel speed as a percent.
    - * Formula: ratio = 100 - abs(turnRate).
    - * When the ratio is negative, the outer and inner wheels rotate in opposite - * directions. Examples of how the formula works: - *

      - *
    • steer(0) -> inner and outer wheels turn at the same - * speed, travel straight - *
    • steer(25) -> the inner wheel turns at 75% of the speed - * of the outer wheel, turn left - *
    • steer(100) -> the inner wheel stops and the outer wheel - * is at 100 percent, turn left - *
    • steer(200) -> the inner wheel turns at the same speed as - * the outer wheel - a zero radius turn. - *
    - *

    - * Note: If you have specified a drift correction in the constructor it will - * not be applied in this method. - * - * @param steerRatio - * If positive, the left side of the robot is on the inside of - * the turn. If negative, the left side is on the outside. - */ - public void steerBackward(double steerRatio); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/Move.java b/ev3classes/src/main/java/lejos/robotics/navigation/Move.java deleted file mode 100644 index 98cc9fd..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/Move.java +++ /dev/null @@ -1,285 +0,0 @@ -package lejos.robotics.navigation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import lejos.robotics.Transmittable; - -/** - * Models a movement performed by a pilot - * - * @author Lawrie Griffiths - * - */ -public class Move implements Transmittable { - /** - * The type of movement made in sufficient detail to allow errors - * in the movement to be modeled. - */ - public enum MoveType {TRAVEL, ROTATE, ARC, STOP} - private float distanceTraveled, angleTurned; - private MoveType moveType; - private float arcRadius = Float.POSITIVE_INFINITY; - private boolean isMoving; - private long timeStamp; - private float travelSpeed, rotateSpeed; - - /** - * Create a movement object to record a movement made by a pilot. - * This method automatically calculates the - * MoveType based on the data as follows:
    - *

  • (distance NOT 0) AND (angle NOT 0) --> ARC - *
  • (distance = 0) AND (angle NOT 0) --> ROTATE - *
  • (distance NOT 0) AND (angle = 0) --> TRAVEL - *
  • (distance = 0) AND (angle = 0) --> STOP - * @param distance the distance traveled in pilot units - * @param angle the angle turned in degrees - * @param isMoving true iff the movement was created while the robot was moving - */ - public Move(float distance, float angle, boolean isMoving) - { - this.moveType = Move.calcMoveType(distance, angle); - this.distanceTraveled = distance; - this.angleTurned = angle; - this.isMoving = isMoving; - // TODO: This works fine, but could use convertDistanceToAngle() instead here? - if (Math.abs(angle) > 0.5) { - double turnRad = Math.toRadians(angle); - arcRadius = (float) (distance / turnRad); - } - this.timeStamp = System.currentTimeMillis(); - } - - /** - * Create a movement object to record a movement made by a pilot. - * @param type the movement type - * @param distance the distance traveled in pilot units - * @param angle the angle turned in degrees - * @param travelSpeed the travel speed - * @param rotateSpeed the rotate speed - * @param isMoving true iff the movement was created while the robot was moving - */ - public Move(MoveType type, float distance, float angle, float travelSpeed, float rotateSpeed, boolean isMoving) - { - this.moveType = type; - this.distanceTraveled = distance; - this.angleTurned = angle; - if (Math.abs(angle) > 0.5) - { - double turnRad = Math.toRadians(angle); - arcRadius = (float) (distance / turnRad); - } - this.travelSpeed = travelSpeed; - this.rotateSpeed = rotateSpeed; - this.isMoving = isMoving; - this.timeStamp = System.currentTimeMillis(); - } - - /** - * Create a movement object to record a movement made by a pilot. - * @param type the movement type - * @param distance the distance traveled in pilot units - * @param angle the angle turned in degrees - * @param isMoving true iff the movement was created while the robot was moving - */ - public Move(MoveType type, float distance, float angle, boolean isMoving) - { - this(type,distance,angle,0f,0f,isMoving); - } - - - /** - * use this method to recycle an existing Move instead of creating a new one - * @param distance - * @param angle - * @param isMoving - */ - public void setValues(MoveType type, float distance, float angle,boolean isMoving) - { - this.moveType = type; - this.distanceTraveled = distance; - this.angleTurned = angle; - this.isMoving = isMoving; - // TODO: This works fine, but could use convertDistanceToAngle() instead here? - if (Math.abs(angle) > 0.5) - { - double turnRad = Math.toRadians(angle); - arcRadius = (float) (distance / turnRad); - } - this.timeStamp = System.currentTimeMillis(); - } - - /** - * use this method to recycle an existing Move instead of creating a new one - * @param travelSpeed the new travelspeed - * @param rotateSpeed the new rotate speed - */ - public void setDynamics(float travelSpeed, float rotateSpeed) - { - this.travelSpeed = travelSpeed; - this.rotateSpeed = rotateSpeed; - } - - /** - * Helper method to calculate the MoveType based on distance, angle, radius parameters. - * - * @param distance - * @param angle - * @return - */ - private static MoveType calcMoveType(float distance, float angle) { - if(distance == 0 & angle == 0) return MoveType.STOP; - else if(distance != 0 & angle == 0) return MoveType.TRAVEL; - else if(distance == 0 & angle != 0) return MoveType.ROTATE; - else return MoveType.ARC; - } - - /** - * Alternate constructor that uses angle and turn radius instead. Useful for constructing arcs, but it - * can't represent a straight line of travel with a set distance (use the other constructor to specify distance). - * This method automatically calculates the MoveType based on the data as follows:
    - *
  • (radius NOT 0) AND (angle NOT 0) --> ARC - *
  • (radius = 0) AND (angle NOT 0) --> ROTATE - *
  • (radius = 0) AND (angle = 0) --> STOP - *
  • (radius = +infinity) AND (angle = 0) --> TRAVEL - *
  • NOTE: can't calculate distance based only on angle and radius, therefore distance can't be calculated and will equal NaN) - * @param isMoving - * @param angle - * @param turnRadius - */ - public Move(boolean isMoving, float angle, float turnRadius) { - this.distanceTraveled = Move.convertAngleToDistance(angle, turnRadius); - this.moveType = Move.calcMoveType(this.distanceTraveled, angle); - this.angleTurned = angle; - this.isMoving = isMoving; - arcRadius = turnRadius; - this.timeStamp = System.currentTimeMillis(); - } - - /** - * Get the distance traveled. This can be in a straight line or an arc path. - * - * @return the distance traveled - */ - public float getDistanceTraveled() { - return distanceTraveled; - } - - /** - * The time stamp is the system clock at the time the Move object is created. It is set automatically - * in the Move constructor using {@link System#currentTimeMillis()} - * @return Time stamp in milliseconds. - */ - public long getTimeStamp() { - return timeStamp; - } - - /** - * Get the angle turned by a rotate or an arc operation. - * - * @return the angle turned - */ - public float getAngleTurned() { - return angleTurned; - } - - /** - * Get the type of the movement performed - * - * @return the movement type - */ - public MoveType getMoveType() { - return moveType; - } - - /** - * Get the radius of the arc - * - * @return the radius of the arc - */ - public float getArcRadius() { - return arcRadius; - } - - /** - * Get the travel speed - * @return the travel speed - */ - public float getTravelSpeed() { - return travelSpeed; - } - - /** - * Get the rotate speed - * @return the rotate speed - */ - public float getRotateSpeed() { - return rotateSpeed; - } - - /** - * Test if move was in progress - * - * @return true iff the robot was moving when this Move object was created - */ - public boolean isMoving() { - return isMoving; - } - - /** - * Static utility method for converting distance (given turn radius) into angle. - * @param distance - * @param turnRadius - * @return angle - */ - public static float convertDistanceToAngle(float distance, float turnRadius){ - return (float)((distance * 360) / (2 * Math.PI * turnRadius)); - } - - /** - * Static utility method for converting angle (given turn radius) into distance. - * @param angle - * @param turnRadius - * @return distance - */ - public static float convertAngleToDistance(float angle, float turnRadius){ - return (float)((angle * 2 * Math.PI * turnRadius) / 360); - } - - public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeByte(moveType.ordinal()); - dos.writeFloat(travelSpeed); - dos.writeFloat(rotateSpeed); - dos.writeFloat(distanceTraveled); - dos.writeFloat(angleTurned); - dos.writeFloat(arcRadius); - dos.flush(); - } - - public void loadObject(DataInputStream dis) throws IOException { - moveType = MoveType.values()[dis.readByte()]; - travelSpeed = dis.readFloat(); - rotateSpeed = dis.readFloat(); - distanceTraveled = dis.readFloat(); - angleTurned = dis.readFloat(); - arcRadius = dis.readFloat(); - } - - @Override - public String toString() { - String s = moveType.name() + " "; - switch(moveType) { - case ROTATE: - s += angleTurned + " at " + rotateSpeed; - break; - case TRAVEL: - s += distanceTraveled + " at " + travelSpeed; - break; - case ARC: - s += " of " + arcRadius + " for " + angleTurned + "degrees at " + travelSpeed; - break; - } - return s; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/MoveController.java b/ev3classes/src/main/java/lejos/robotics/navigation/MoveController.java deleted file mode 100644 index cafc8fc..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/MoveController.java +++ /dev/null @@ -1,95 +0,0 @@ -package lejos.robotics.navigation; - -public interface MoveController extends MoveProvider { - /** - * NXT 1.0 kit wheel diameter, in centimeters - */ - public static final double WHEEL_SIZE_NXT1 = 5.60; - - /** - * NXT 2.0 kit wheel diameter, in centimeters - */ - public static final double WHEEL_SIZE_NXT2 = 4.32; - - /** - * EV3 kit wheel diameter, in centimeters - */ - public static final double WHEEL_SIZE_EV3 = WHEEL_SIZE_NXT2; - - /** - * White RCX "motorcycle" wheel diameter, in centimeters - */ - public static final double WHEEL_SIZE_RCX = 8.16; - - /** - *Starts the NXT robot moving forward. - */ - public void forward(); - - /** - *Starts the NXT robot moving backwards. - */ - public void backward(); - - /** - * Halts the NXT robot - */ - public void stop(); - - /** - * true if the robot is moving - * @return true if the robot is moving under power. - */ - public boolean isMoving(); - - - /** - * Moves the NXT robot a specific distance. A positive value moves it forward and a negative value moves it backward. - * Method returns when movement is done. - * - * @param distance The positive or negative distance to move the robot. - */ - public void travel(double distance); - - /** - * Moves the NXT robot a specific distance. A positive value moves it forward and a negative value moves it backward. - * @param distance The positive or negative distance to move the robot, in wheel diameter units. - * @param immediateReturn If immediateReturn is true then the method returns immediately. - */ - public void travel(double distance, boolean immediateReturn); - - /** - * Sets the speed at which the robot will travel forward and backward (and to some extent arcs, although actual arc speed - * is slightly less). Speed is measured in units/second. e.g. If wheel diameter is cm, then speed is cm/sec. - * @param speed In chosen units per second (e.g. cm/sec) - */ - public void setLinearSpeed(double speed); - - /** - * Returns the speed at which the robot will travel forward and backward (and to some extent arcs, although actual arc speed - * is slightly less). Speed is measured in units/second. e.g. If wheel diameter is cm, then speed is cm/sec. - * @return Speed in chosen units per second (e.g. cm/sec) - */ - public double getLinearSpeed(); - - /** - * Returns the maximum speed at which this robot is capable of traveling forward and backward. - * Speed is measured in units/second. e.g. If wheel diameter is cm, then speed is cm/sec. - * @return Speed in chosen units per second (e.g. cm/sec) - */ - public double getMaxLinearSpeed(); - - /** - * Sets the acceleration at which the robot will accelerate at the start of a move and decelerate at the end of a move. - * Acceleration is measured in units/second^2. e.g. If wheel diameter is cm, then acceleration is cm/sec^2.

    - * If acceleration is set during a move it will not be in used for the current move, it will be in effect with the next move. - * @param acceleration in chosen units/second^2 - */ - public void setLinearAcceleration(double acceleration); - - /** Returns the acceleration at which the robot accelerates at the start of a move and decelerates at the end of a move. - * @return acceleration in chosen units/second^2 - */ - public double getLinearAcceleration(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/MoveListener.java b/ev3classes/src/main/java/lejos/robotics/navigation/MoveListener.java deleted file mode 100644 index 0f9e4df..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/MoveListener.java +++ /dev/null @@ -1,37 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.navigation.Move; - -/** - *

    Any class that wants to be updated automatically by a MoveProvider should - * implement this interface. Both movementStarted() and movementStopped() also return - * a MoveProvider object.

    - * - *

    There are several practical scenarios to use a MoveListener. If you have a robot that has a range scanner - * pointed forward and mounted on a motor, a MoveListener could listen for arc movements and rotate the scanner - * left or right if the vehicle begins steering around a corner so the sensor is pointed where the robot is traveling.

    - * - *

    In another scenario, a MoveListener GUI can listen for movements from multiple MovementProviders. It - * might want to draw one robot as blue, one as green, one as red, etc.. - * The MoveProvider allows it to differentiate the MovementProviders from one another.

    - * - * @author nxj team - */ -public interface MoveListener { - - /** - * Called when a Move Provider starts a move - * - * @param event the movement - * @param mp the movement provider - */ - public void moveStarted(Move event, MoveProvider mp); - - /** - * Called by the movement provider when a move stops - * - * @param event the movement - * @param mp movement provider - */ - public void moveStopped(Move event, MoveProvider mp); -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/MovePilot.java b/ev3classes/src/main/java/lejos/robotics/navigation/MovePilot.java deleted file mode 100644 index 675b9bf..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/MovePilot.java +++ /dev/null @@ -1,426 +0,0 @@ -package lejos.robotics.navigation; -import java.util.ArrayList; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.chassis.Chassis; -import lejos.robotics.chassis.Wheel; -import lejos.robotics.chassis.WheeledChassis; -import lejos.robotics.navigation.Move; -import lejos.robotics.navigation.MoveListener; - -/** - * The Pilot class is a software abstraction of the Pilot mechanism - * of a robot. It contains methods to control robot movements: travel forward or - * backward in a straight line or a circular path or rotate to a new direction.
    - * This class will work with any chassis. Some types of chassis might not support all the - * movements this pilot support. - * An object of this class assumes that it has exclusive control of - * its motors. If any other object makes calls to its motors, the results are - * unpredictable.
    - * It automatically updates a - * {@link lejos.robotics.localization.OdometryPoseProvider} which has called the - * addMoveListener method on this object.
    - * Some methods optionally return immediately so the thread that called it can - * do things while the robot is moving, such as monitor sensors and call - * {@link #stop()}.
    - * Handling stalls: If a stall is detected, isStalled() returns - * - * true , isMoving() returns false, - * moveStopped() - * is called, and, if a blocking method is executing, that method exits. - * The units of measure for travel distance, speed and acceleration are the - * units used in specifying the wheel diameter in the - * chassis.
    - * In all the methods that cause the robot to change its heading (the angle - * relative to the X axis in which the robot is facing) the angle parameter - * specifies the change in heading. A positive angle causes a turn to the left - * (anti-clockwise) to increase the heading, and a negative angle causes a turn - * to the right (clockwise).
    - * Example of use of come common methods: - *

    - *

    - * Wheel wheel1 = DifferentialChassis.modelWheel(Motor.A, 43.2).offset(-72);
    - * Wheel wheel2 = DifferentialChassis.modelWheel(Motor.D, 43.2).offset(72);
    - * Chassis chassis = new DifferentialChassis(new Wheel[]{wheel1, wheel2}); 
    - * MovePilot pilot = new MovePilot(chassis);
    - * pilot.setRobotSpeed(30);  // cm per second
    - * pilot.travel(50);         // cm
    - * pilot.rotate(-90);        // degree clockwise
    - * pilot.travel(-50,true);  //  move backward for 50 cm
    - * while(pilot.isMoving())Thread.yield();
    - * pilot.rotate(-90);
    - * pilot.rotateTo(270);
    - * pilot.stop();
    - * 
    - *

    - * - * - **/ -public class MovePilot implements ArcRotateMoveController { - private double minRadius = 0; - final private Chassis chassis; - private ArrayList _listeners = new ArrayList(); - private double linearSpeed; - private double linearAcceleration; - private double angularAcceleration; - private double angularSpeed; - private Monitor _monitor; - private boolean _moveActive = false; - private Move move = null; - private boolean _replaceMove = false; - - /** - * Allocates a Pilot object, and sets the physical parameters of - * the robot.
    - * Assumes Motor.forward() causes the robot to move forward. - * - * @param wheelDiameter - * Diameter of the tire, in any convenient units (diameter in mm is - * usually printed on the tire). - * @param trackWidth - * Distance between center of right tire and center of left tire, in - * same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - */ - @Deprecated - public MovePilot(final double wheelDiameter, final double trackWidth, final RegulatedMotor leftMotor, - final RegulatedMotor rightMotor) { - this(wheelDiameter, trackWidth, leftMotor, rightMotor, false); - } - - /** - * Allocates a Pilot object, and sets the physical parameters of - * the robot.
    - * - * @param wheelDiameter - * Diameter of the tire, in any convenient units (diameter in mm is - * usually printed on the tire). - * @param trackWidth - * Distance between center of right tire and center of left tire, in - * same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - * @param reverse - * If true, the NXT robot moves forward when the motors are running - * backward. - */ - @Deprecated - public MovePilot(final double wheelDiameter, final double trackWidth, final RegulatedMotor leftMotor, - final RegulatedMotor rightMotor, final boolean reverse) { - this(wheelDiameter, wheelDiameter, trackWidth, leftMotor, rightMotor, reverse); - } - - /** - * Allocates a Pilot object, and sets the physical parameters of - * the robot.
    - * - * @param leftWheelDiameter - * Diameter of the left wheel, in any convenient units (diameter in - * mm is usually printed on the tire). - * @param rightWheelDiameter - * Diameter of the right wheel. You can actually fit intentionally - * wheels with different size to your robot. If you fitted wheels - * with the same size, but your robot is not going straight, try - * swapping the wheels and see if it deviates into the other - * direction. That would indicate a small difference in wheel size. - * Adjust wheel size accordingly. The minimum change in wheel size - * which will actually have an effect is given by minChange = - * A*wheelDiameter*wheelDiameter/(1-(A*wheelDiameter) where A = - * PI/(moveSpeed*360). Thus for a moveSpeed of 25 cm/second and a - * wheelDiameter of 5,5 cm the minChange is about 0,01058 cm. The - * reason for this is, that different while sizes will result in - * different motor speed. And that is given as an integer in degree - * per second. - * @param trackWidth - * Distance between center of right tire and center of left tire, in - * same units as wheelDiameter. - * @param leftMotor - * The left Motor (e.g., Motor.C). - * @param rightMotor - * The right Motor (e.g., Motor.A). - * @param reverse - * If true, the NXT robot moves forward when the motors are running - * backward. - */ - @Deprecated - public MovePilot(final double leftWheelDiameter, final double rightWheelDiameter, final double trackWidth, - final RegulatedMotor leftMotor, final RegulatedMotor rightMotor, final boolean reverse) { - this(new WheeledChassis(new Wheel[] { - WheeledChassis.modelWheel(leftMotor, leftWheelDiameter).offset(trackWidth / 2).invert(reverse), - WheeledChassis.modelWheel(rightMotor, rightWheelDiameter).offset(-trackWidth / 2).invert(reverse) }, WheeledChassis.TYPE_DIFFERENTIAL)); - } - - /** - * Allocates a Pilot object.
    - * - * @param chassis - * A Chassis object describing the physical parameters of the robot. - */ - public MovePilot(Chassis chassis) { - this.chassis = chassis; - linearSpeed = chassis.getMaxLinearSpeed() * 0.8; - angularSpeed = chassis.getMaxAngularSpeed() * 0.8; - chassis.setSpeed(linearSpeed, this.angularSpeed); - linearAcceleration = getLinearSpeed() * 4; - angularAcceleration = getAngularSpeed() * 4; - chassis.setAcceleration(linearAcceleration, angularAcceleration); - minRadius = chassis.getMinRadius(); - _monitor = new Monitor(); - _monitor.start(); - - } - - // Getters and setters of dynamics - - @Override - public void setLinearAcceleration(double acceleration) { - linearAcceleration = acceleration; - chassis.setAcceleration(linearAcceleration, angularAcceleration); - } - - @Override - public double getLinearAcceleration() { - return linearAcceleration; - } - - @Override - public void setAngularAcceleration(double acceleration) { - angularAcceleration = acceleration; - chassis.setAcceleration(linearAcceleration, angularAcceleration); - } - - @Override - public double getAngularAcceleration() { - return angularAcceleration; - } - - @Override - public void setLinearSpeed(double speed) { - linearSpeed = speed; - chassis.setSpeed(linearSpeed, angularSpeed); - } - - @Override - public double getLinearSpeed() { - return linearSpeed; - } - - @Override - public double getMaxLinearSpeed() { - return chassis.getMaxLinearSpeed(); - } - - @Override - public void setAngularSpeed(double speed) { - angularSpeed = speed; - chassis.setSpeed(linearSpeed, angularSpeed); - } - - @Override - public double getAngularSpeed() { - return angularSpeed; - } - - @Override - public double getMaxAngularSpeed() { - return chassis.getMaxAngularSpeed(); - } - - @Override - public double getMinRadius() { - return minRadius; - } - - @Override - public void setMinRadius(double radius) { - minRadius = radius; - } - - // Moves of the travel family - - @Override - public void forward() { - travel(Double.POSITIVE_INFINITY, true); - - } - - @Override - public void backward() { - travel(Double.NEGATIVE_INFINITY, true); - } - - @Override - public void travel(double distance) { - travel(distance, false); - - } - - @Override - public void travel(double distance, boolean immediateReturn) { - if (chassis.isMoving()) - stop(); - move = new Move(Move.MoveType.TRAVEL, (float) distance, 0, (float) linearSpeed, (float) angularSpeed, chassis.isMoving()); - chassis.moveStart(); - chassis.travel(distance); - movementStart(immediateReturn); - } - - // Moves of the Arc family - - @Override - public void arcForward(double radius) { - arc(radius, Double.POSITIVE_INFINITY, true); - } - - @Override - public void arcBackward(double radius) { - arc(radius, Double.NEGATIVE_INFINITY, true); - } - - @Override - public void arc(double radius, double angle) { - arc(radius, angle, false); - } - - @Override - public void travelArc(double radius, double distance) { - travelArc(radius, distance, false); - } - - @Override - public void travelArc(double radius, double distance, boolean immediateReturn) { - arc(radius, distance / (2 * Math.PI), immediateReturn); - } - - @Override - public void rotate(double angle) { - rotate(angle, false); - } - - @Override - public void rotate(double angle, boolean immediateReturn) { - arc(0, angle, immediateReturn); - } - - public void rotateLeft() { - rotate(Double.POSITIVE_INFINITY, true); - } - - public void rotateRight() { - rotate(Double.NEGATIVE_INFINITY, true); - } - - - @Override - public void arc(double radius, double angle, boolean immediateReturn) { - if (Math.abs(radius) < minRadius) { - throw new RuntimeException("Turn radius too small."); - } - if (_moveActive) { - stop(); - } - if (radius == 0) { - move = new Move(Move.MoveType.ROTATE, 0, (float) angle, (float) linearSpeed, (float) angularSpeed, chassis.isMoving()); - } else { - move = new Move(Move.MoveType.ARC, (float) (Math.toRadians(angle) * radius), (float) angle, (float) linearSpeed, (float) angularSpeed, - chassis.isMoving()); - } - chassis.moveStart(); - chassis.arc(radius, angle); - movementStart(immediateReturn); - } - - // Stops. Stops must be blocking! - - @Override - public void stop() { - // This method must be blocking - chassis.stop(); - while (_moveActive) Thread.yield(); - } - - // State - @Override - public boolean isMoving() { - return chassis.isMoving(); - } - - - - // Methods dealing the start and end of a move - private void movementStart(boolean immediateReturn) { - for (MoveListener ml : _listeners) - ml.moveStarted(move, this); - _moveActive = true; - synchronized (_monitor) { - _monitor.notifyAll(); - } - if (immediateReturn) return; - while (_moveActive) Thread.yield(); - } - - private void movementStop() { - if ( ! _listeners.isEmpty()) { - chassis.getDisplacement(move); - for (MoveListener ml : _listeners) - ml.moveStopped(move, this); - } - _moveActive = false; - } - - @Override - public Move getMovement() { - if (_moveActive) { - return chassis.getDisplacement(move); - } - else { - return new Move(Move.MoveType.STOP, 0, 0, false); - } - } - - @Override - public void addMoveListener(MoveListener listener) { - _listeners.add(listener); - - } - - /** - * The monitor class detects end-of-move situations when non blocking move - * call were made and makes sure these are dealt with. - * - */ - private class Monitor extends Thread { - public boolean more = true; - - public Monitor() { - setDaemon(true); - } - - public synchronized void run() { - while (more) { - if (_moveActive) { - if (chassis.isStalled()) - MovePilot.this.stop(); - if (!chassis.isMoving() || _replaceMove) { - movementStop(); - _moveActive = false; - _replaceMove = false; - } - } - // wait for an event - try { - wait(_moveActive ? 1 : 100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/MoveProvider.java b/ev3classes/src/main/java/lejos/robotics/navigation/MoveProvider.java deleted file mode 100644 index 682b258..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/MoveProvider.java +++ /dev/null @@ -1,26 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.navigation.Move; - -/** - * Should be implemented by a Pilot that provides a partial movement to a pose - * when requested. - * - * @author nxj team - */ -public interface MoveProvider { - - /** - * Returns the move made since the move started, but before it has completed. This method is used - * by GUI maps to display the movement of a robot in real time. The robot must be capable of determining - * the move while it is in motion. - * @return The move made since the move started. - */ - public Move getMovement(); - - /** - * Adds a MoveListener that will be notified of all movement events. - * @param listener the move listener - */ - public void addMoveListener(MoveListener listener); -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/NavigationListener.java b/ev3classes/src/main/java/lejos/robotics/navigation/NavigationListener.java deleted file mode 100644 index 6d7f403..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/NavigationListener.java +++ /dev/null @@ -1,36 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.navigation.Pose; -import lejos.robotics.navigation.Waypoint; - -/** - * Interface for informing listeners that a way point has been reached. - * - */ -public interface NavigationListener -{ - - /** - * Called when the robot has reached a new Wahpoint. - * @param waypoint where the robot - * @param pose of the robot - * @param sequence of the Waypoint in the path - */ - public void atWaypoint(Waypoint waypoint, Pose pose, int sequence); - -/** - * Called when the robot has reached the last Waypoint of the path - * @param waypoint where the robot - * @param pose of the robot - * @param sequence of the Waypoint in the path - */ - public void pathComplete(Waypoint waypoint, Pose pose, int sequence); - -/** - * called when the robot has stopped, not at a Waypoint - * @param waypoint toward which the robot was moving - * @param pose current pose of the robot - * @param sequence number of the next Waypoint - */ - public void pathInterrupted(Waypoint waypoint, Pose pose, int sequence); -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/Navigator.java b/ev3classes/src/main/java/lejos/robotics/navigation/Navigator.java deleted file mode 100644 index f6931fc..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/Navigator.java +++ /dev/null @@ -1,461 +0,0 @@ -package lejos.robotics.navigation; - -import java.util.ArrayList; - -import lejos.robotics.localization.OdometryPoseProvider; -import lejos.robotics.localization.PoseProvider; -import lejos.robotics.pathfinding.Path; - -/** - * This class controls a robot to traverse a Path, a sequence of {@link lejos.robotics.navigation.Waypoint}s. - * It's default mode for a new path is continuous movement (no stopping at waypoints) but see also {@link #singleStep(boolean)}. To interrupt the path traversal, call stop(). - * It uses an inner class running its own thread to issue movement commands to its - * {@link lejos.robotics.navigation.MoveController}, - * which can be either a {@link lejos.robotics.navigation.DifferentialPilot} - * or {@link lejos.robotics.navigation.SteeringPilot}. - * It also uses a {@link lejos.robotics.localization.PoseProvider} - * Calls its {@link lejos.robotics.navigation.NavigationListener}s - * when a Waypoint is reached or the robot stops. - * This class has only one blocking method: {@link #waitForStop()} . - * @author Roger Glassey - */ -public class Navigator implements WaypointListener -{ - - /** - * Allocates a Navigator object, using pilot that implements the ArcMoveController interface. - * @param pilot - */ - public Navigator(MoveController pilot) - { - this(pilot, null); - } - - /** - * Allocates a Navigator object using a pilot and a custom poseProvider, rather than the default - * OdometryPoseProvider. - * @param pilot the pilot - * @param poseProvider the custom PoseProvider - */ - public Navigator(MoveController pilot, PoseProvider poseProvider) - { - _pilot = pilot; - if (poseProvider == null) - this.poseProvider = new OdometryPoseProvider(_pilot); - else - this.poseProvider = poseProvider; - _radius = (_pilot instanceof ArcMoveController ? ((ArcMoveController) _pilot).getMinRadius() : 0); - _nav = new Nav(); - _nav.setDaemon(true); - _nav.start(); - } - - /** - * Sets the PoseProvider after construction of the Navigator - * @param aProvider the PoseProvider - */ - public void setPoseProvider(PoseProvider aProvider) - { - poseProvider = aProvider; - } - - /** - * Adds a NavigationListener that is informed when a the robot stops or - * reaches a WayPoint. - * @param listener the NavitationListener - */ - public void addNavigationListener(NavigationListener listener) - { - _listeners.add(listener); - } - - /** - * Returns the PoseProvider - * @return the PoseProvider - */ - public PoseProvider getPoseProvider() - { - return poseProvider; - } - - /** - * Returns the MoveController belonging to this object. - * @return the pilot - */ - public MoveController getMoveController() - { - return _pilot; - } - - /** - * Sets the path that the Navigator will traverse. - * By default, the robot will not stop along the way. - * If the robot is moving when this method is called, it stops and the current - * path is replaced by the new one. - * @param path to be followed. - */ - public void setPath(Path path) - { - if (_keepGoing) - stop(); - _path = path; - _singleStep = false; - _sequenceNr = 0; - } - - /** - * Clears the current path. - * If the robot is moving when this method is called, it stops; - */ - public void clearPath() { - if (_keepGoing) - stop(); - _path.clear(); - } - - /** - * Gets the current path - * - * @return the path - */ - public Path getPath() { - return _path; - } - - /** - * Starts the robot traversing the path. This method is non-blocking. - * @param path to be followed. - */ - public void followPath(Path path) - { - _path = path; - followPath(); - } - - /** - * Starts the robot traversing the current path. - * This method is non-blocking; - */ - public void followPath() - { - if (_path.isEmpty()) - return; - _interrupted = false; - _keepGoing = true; -// RConsole.println("navigator followPath called"); - } - - /** - * Controls whether the robot stops at each Waypoint; applies to the current path only. - * The robot will move to the next Waypoint if you call {@link #followPath()}. - * @param yes if true , the robot stops at each Waypoint. - */ - public void singleStep(boolean yes) - { - _singleStep = yes; - } - - /** - * Starts the robot moving toward the destination. - * If no path exists, a new one is created consisting of the destination, - * otherwise the destination is added to the path. This method is non-blocking, and is - * equivalent to {@linkplain #addWaypoint(Waypoint) addWaypoint(destination);} - * {@linkplain #followPath() followPath();} - * @param destination the waypoint to be reached - */ - public void goTo(Waypoint destination) - { - addWaypoint(destination); - followPath(); - - } - - /** - * Starts the moving toward the destination Waypoint created from - * the parameters. - * If no path exists, a new one is created, - * otherwise the new Waypoint is added to the path. This method is non-blocking, and is - * equivalent to - add(float x, float y); followPath(); - * @param x coordinate of the destination - * @param y coordinate of the destination - */ - public void goTo(float x, float y) - { - goTo(new Waypoint(x, y)); - } - - /** - * Starts the moving toward the destination Waypoint created from - * the parameters. - * If no path exists, a new one is created, - * otherwise the new Waypoint is added to the path. This method is non-blocking, and is - * equivalent to - add(float x, float y); followPath(); - * @param x coordinate of the destination - * @param y coordinate of th destination - * @param heading desired robot heading at arrival - */ - public void goTo(float x, float y, float heading) - { - goTo(new Waypoint(x, y, heading)); - } - - /** - * Rotates the robot to a new absolute heading. For example, rotateTo(0) will line the robot with the - * x-axis, while rotateTo(90) lines it with the y-axis. If the robot is currently on the move to a - * coordinate, this method will not attempt to rotate and it will return false. - * @param angle The absolute heading to rotate the robot to. Value is 0 to 360. - * @return true if the rotation happened, false if the robot was moving while this method was called. - */ - public boolean rotateTo(double angle) { - float head = getPoseProvider().getPose().getHeading(); - double diff = angle - head; - while(diff > 180) diff = diff - 360; - while(diff < -180) diff = diff + 360; - if(isMoving()) return false; - if(_pilot instanceof RotateMoveController) - ((RotateMoveController) _pilot).rotate(diff,false); - return true; - - } - - /** - * Adds a Waypoint to the end of the path. - * Call {@link #followPath()} to start moving the along the current path. - * - * @param aWaypoint to be added - */ - public void addWaypoint(Waypoint aWaypoint) - { - if(_path.isEmpty()) - { - _sequenceNr = 0; - _singleStep = false; - } - _path.add(aWaypoint); - } - - /** - * Constructs an new Waypoint from the parameters and adds it to the end of the path. - * Call {@link #followPath()} to start moving the along the current path. - * - * @param x coordinate of the waypoint - * @param y coordinate of the waypoint - */ - public void addWaypoint(float x, float y) - { - addWaypoint(new Waypoint(x, y)); - } - - /** - * Constructs an new Waypoint from the parameters and adds it to the end of the path. - * Call {@link #followPath()} to start moving the along the current path. - * - * @param x coordinate of the waypoint - * @param y coordinate of the waypoint - * @param heading the heading of the robot when it reaches the waypoint - */ - public void addWaypoint(float x, float y, float heading) - { - addWaypoint(new Waypoint(x, y, heading)); - } - - /** - * Stops the robot. - * The robot will resume its path traversal if you call {@link #followPath()}. - */ - public void stop() - { - _keepGoing = false; - _pilot.stop(); - _interrupted = true; - callListeners(); - } - - /** - * Returns the waypoint to which the robot is presently moving. - * @return the waypoint ; null if the path is empty. - */ - public Waypoint getWaypoint() - { - if (_path.size() <= 0) - return null; - return _path.get(0); - } - - /** - * Returns true if the the final waypoint has been reached - * @return true if the path is completed - */ - public boolean pathCompleted() - { - return _path.size() == 0; - } - - /** - * Waits for the robot to stop for any reason ; - * returns true if the robot stopped at the final Waypoint of - *the path. - * @return true if the path is completed - */ - public boolean waitForStop() - { - while (_keepGoing) - Thread.yield(); - return _path.isEmpty(); - } - - /** - * Returns true if the robot is moving toward a waypoint. - * @return true if moving. - */ - public boolean isMoving() - { - return _keepGoing; - } - - public void pathGenerated() { - // Currently does nothing - } - - private void callListeners() - { - if (_listeners != null) - { - _pose = poseProvider.getPose(); -// RConsole.println("listener called interrupt"+_interrupted +" done "+_path.isEmpty()+" "+_pose); - for (NavigationListener l : _listeners) - if (_interrupted) - l.pathInterrupted(_destination, _pose, _sequenceNr); - else - { - l.atWaypoint(_destination, _pose, _sequenceNr); - if (_path.isEmpty()) - l.pathComplete(_destination, _pose, _sequenceNr); - } - } - } - - /** - * This inner class runs the thread that processes the waypoint queue - */ - private class Nav extends Thread - { - boolean more = true; - - @Override - public void run() - { - while (more) - { - while (_keepGoing && _path != null && ! _path.isEmpty()) - { - _destination = _path.get(0); - _pose = poseProvider.getPose(); -// RConsole.println("NAV loop begin "+_destination); - float destinationRelativeBearing = _pose.relativeBearing(_destination); - if(!_keepGoing) break; - if(_radius == 0) // differential pilot used - { - ((RotateMoveController) _pilot).rotate(destinationRelativeBearing,true); - while (_pilot.isMoving() && _keepGoing)Thread.yield(); - if(!_keepGoing) break; - } - else // begin arc direction change - { - // 1. Get shortest path: - Move [] moves; - double minRadius = (_pilot instanceof ArcMoveController ? - ((ArcMoveController) _pilot).getMinRadius() : 0); - - if (_destination.headingRequired) - { - moves = ArcAlgorithms.getBestPath(poseProvider.getPose(), - (float)minRadius, _destination.getPose(),(float)minRadius); - } - else - { - moves = ArcAlgorithms.getBestPath(poseProvider.getPose(), - _destination, (float)minRadius); - } - // 2. Drive the path - for(int i=0;i _listeners = new ArrayList(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/OmniPilot.java b/ev3classes/src/main/java/lejos/robotics/navigation/OmniPilot.java deleted file mode 100644 index 743b17f..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/OmniPilot.java +++ /dev/null @@ -1,842 +0,0 @@ -package lejos.robotics.navigation; - -import java.util.ArrayList; - -import lejos.hardware.Power; -import lejos.robotics.Gyroscope; -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; -import lejos.robotics.geometry.Point; -import lejos.robotics.navigation.Pose; -import lejos.utility.Delay; -import lejos.utility.Matrix; - -/* - * - * central wheel - * | - * | - * 120� | 120� - * / \ - * / \ - * /120� \ - * left wheel right wheel - * - * wi is the i-th wheel angular speed in [rad/s] - * Vx and Vy are the components of the speed vector expressed in the robot local reference frame - * thetadot is the robot angular speed - * [Vx, Vy, thetadot]' = kMatrix*[w1, w2, w3]' - * [w1, w2, w3]' = ikMatrix*[Vx, Vy, thetadot]' - * [dx, dy, dh]' = kMatrix*[dr1, dr2, dr3]' - */ - -/** - *

    Use the OmniPilot class to control holonomic vehicles with three omnidirectional wheels - * that allow the robot to move in any direction without changing heading. - * The robot can also spin while driving straight, and perform any kind of maneuvre the other steering and differential drive vehicles can do. - * The odometry is computed by this class directly. - * For the class to work properly, take care to design the robot symmetrically, so that the three wheel axes meet in the center of the robot.

    - * @author Daniele Benedettelli - * @deprecated use {@link MovePilot} instead. - * - */ -@Deprecated -public class OmniPilot implements ArcRotateMoveController, RegulatedMotorListener { - - private Pose pose = new Pose(); // TODO: Technically this variable should be removed. Navigator handles Pose. - private float wheelBase = 7.0f; // units - private float wheelDiameter = 4.6f; // units - private double[][] ikPars; - private double[][] kPars; - private Matrix ikMatrix; // inverse kinematics matrix - private Matrix kMatrix; // direct kinematics matrix - private float linearSpeed = 10; //units/s - private boolean reverse = false; // true when linearSpeed is negative - private float speedVectorDirection = 0; - private float angularSpeed = 0; // deg/s - private final RegulatedMotor motor1; // central motor - private final RegulatedMotor motor2; // left motor - private final RegulatedMotor motor3; // right motor - private int motor1Speed = 0; //deg/s - private int motor2Speed = 0; //deg/s - private int motor3Speed = 0; //deg/s - private Odometer odo = new Odometer(); - private boolean spinningMode = false; - private float spinLinSpeed = 0; // units/s - private float spinAngSpeed = 0; // deg/s - private float spinTravelDirection = 0; // deg - private Power battery; - - private double minTurnRadius = 0; // This vehicle can turn withgout moving therefore minimum turn radius = 0 - - private Gyroscope gyro; - - private boolean gyroEnabled = false; - - /** - * MoveListeners to notify when a move is started or stopped. - */ - private ArrayList listeners= new ArrayList(); - private int acceleration; - - /** - * Instantiates a new omnidirectional pilot. - * This class also keeps track of the odometry - * Express the distances in the units you prefer (mm, in, cm ...) - * - * @param wheelDistanceFromCenter the wheel distance from center - * @param wheelDiameter the wheel diameter - * @param centralMotor the central motor - * @param CW120degMotor the motor at 120 degrees clockwise from front - * @param CCW120degMotor the motor at 120 degrees counter-clockwise from front - * @param centralWheelFrontal if true, the central wheel frontal else it is facing back - * @param motorReverse if motors are mounted reversed - */ - public OmniPilot (float wheelDistanceFromCenter, float wheelDiameter, - RegulatedMotor centralMotor, RegulatedMotor CW120degMotor, RegulatedMotor CCW120degMotor, - boolean centralWheelFrontal, boolean motorReverse, - Power battery) { - this.wheelBase = wheelDistanceFromCenter; - this.wheelDiameter = wheelDiameter; - this.motor1 = centralMotor; - this.motor2 = CCW120degMotor; - this.motor3 = CW120degMotor; - this.battery = battery; - motor1.addListener(this); - motor2.addListener(this); - motor3.addListener(this); - initMatrices(centralWheelFrontal, motorReverse); - odo.setDaemon(true); -// odo.setPriority(6); - odo.start(); - } - - /** - * Instantiates a new omnidirectional pilot. - * This class also keeps track of the odometry - * Express the distances in the units you prefer (mm, in, cm ...) - * This constructor allows you to add a cruizcore gyro for accurate odometry and spinning - * - * @param wheelDistanceFromCenter the wheel distance from center - * @param wheelDiameter the wheel diameter - * @param centralMotor the central motor - * @param CW120degMotor the motor at 120 degrees clockwise from front - * @param CCW120degMotor the motor at 120 degrees counter-clockwise from front - * @param centralWheelFrontal if true, the central wheel frontal else it is facing back - * @param motorReverse if motors are mounted reversed - * @param gyro the gyroscope - */ - public OmniPilot(float wheelDistanceFromCenter, float wheelDiameter, - RegulatedMotor centralMotor, RegulatedMotor CW120degMotor, RegulatedMotor CCW120degMotor, - boolean centralWheelFrontal, boolean motorReverse, - Power battery, Gyroscope gyro) { - this(wheelDistanceFromCenter, wheelDiameter,centralMotor, CW120degMotor, CCW120degMotor, - centralWheelFrontal, motorReverse, battery); - this.gyro = gyro; -// gyro = new CruizcoreGyro(gyroPort), I2CPort.HIGH_SPEED); -// gyro = new CruizcoreGyro(gyroPort, I2CPort.LEGO_MODE); - gyro.reset(); - - gyroEnabled = true; - } - -/* - private void showMatrices() { - LCD.clear(); - System.out.println("ikM row 1 "); - System.out.println((float)ikMatrix.get(0, 0)); - System.out.println((float)ikMatrix.get(0, 1)); - System.out.println((float)ikMatrix.get(0, 2)); - Button.waitForPress(); - System.out.println("ikM row 2 "); - System.out.println((float)ikMatrix.get(1, 0)); - System.out.println((float)ikMatrix.get(1, 1)); - System.out.println((float)ikMatrix.get(1, 2)); - Button.waitForPress(); - System.out.println("ikM row 3 "); - System.out.println((float)ikMatrix.get(2, 0)); - System.out.println((float)ikMatrix.get(2, 1)); - System.out.println((float)ikMatrix.get(2, 2)); - Button.waitForPress(); - LCD.clear(); - System.out.println("kM row 1 "); - System.out.println((float)kMatrix.get(0, 0)); - System.out.println((float)kMatrix.get(0, 1)); - System.out.println((float)kMatrix.get(0, 2)); - Button.waitForPress(); - System.out.println("kM row 2 "); - System.out.println((float)kMatrix.get(1, 0)); - System.out.println((float)kMatrix.get(1, 1)); - System.out.println((float)kMatrix.get(1, 2)); - Button.waitForPress(); - System.out.println("kM row 3 "); - System.out.println((float)kMatrix.get(2, 0)); - System.out.println((float)kMatrix.get(2, 1)); - System.out.println((float)kMatrix.get(2, 2)); - Button.waitForPress(); - } -*/ - - /** - * Inits the matrices. - * - * @param centralWheelForward the central wheel forward - * @param motorReverse the motor reverse - */ -private void initMatrices(boolean centralWheelForward, boolean motorReverse) { - ikPars = new double[3][3]; - kPars = new double[3][3]; - int centralFwd = centralWheelForward? 1: -1; - int rev = motorReverse? -1: 1; - // front/back motor row - ikPars[0][0] = 0; - ikPars[0][1] = -1*centralFwd; - ikPars[0][2] = -wheelBase; - // left motor row - ikPars[1][0] = Math.sqrt(3)*centralFwd/2; - ikPars[1][1] = 0.5*centralFwd; - ikPars[1][2] = -wheelBase; - // right motor row - ikPars[2][0] = -Math.sqrt(3)*centralFwd/2; - ikPars[2][1] = 0.5*centralFwd; - ikPars[2][2] = -wheelBase; - ikMatrix = new Matrix(ikPars,3,3); - ikMatrix.timesEquals(rev*2/wheelDiameter); - - // front/back motor column - kPars[0][0] = 0; - kPars[1][0] = -2*centralFwd; - kPars[2][0] = -1/wheelBase; - // left motor column - kPars[0][1] = Math.sqrt(3)*centralFwd; - kPars[1][1] = 1*centralFwd; - kPars[2][1] = -1/wheelBase; - // right motor column - kPars[0][2] = -Math.sqrt(3)*centralFwd; - kPars[1][2] = 1*centralFwd; - kPars[2][2] = -1/wheelBase; - kMatrix = new Matrix(kPars,3,3); - kMatrix.timesEquals(rev*wheelDiameter/6); - } - - - /** - * Sets the speed. - * - * @param linSpeed the lin speed - * @param dir the dir - * @param angSpeed the ang speed - */ - private void setSpeed(double linSpeed, double dir, double angSpeed) { - double ang = Math.toRadians(dir); - double angspd = Math.toRadians(angSpeed); - double[] spd = {linSpeed*Math.cos(ang), linSpeed*Math.sin(ang), angspd}; - Matrix speeds = new Matrix(spd, 3); - Matrix commands = ikMatrix.times(speeds); - - motor1Speed = (int) Math.toDegrees(commands.get(0, 0)); - motor2Speed = (int) Math.toDegrees(commands.get(1, 0)); - motor3Speed = (int) Math.toDegrees(commands.get(2, 0)); -// LCD.drawString("Vx "+(float)spd[0]+" ", 0, 0); -// LCD.drawString("Vy "+(float)spd[1]+" ", 0, 1); -// LCD.drawString("ang spd "+angSpeed+" ", 0, 2); -// LCD.drawString("w1 "+motor1Speed+" deg/s ", 0, 3); -// LCD.drawString("w2 "+motor2Speed+" deg/s ", 0, 4); -// LCD.drawString("w3 "+motor3Speed+" deg/s ", 0, 5); -// Button.waitForPress(); - motor1.setSpeed(motor1Speed); - motor2.setSpeed(motor2Speed); - motor3.setSpeed(motor3Speed); - } - - @Override - public void setLinearAcceleration(double accel) { - // TODO: take relative wheel speeds into account - this.acceleration = (int) accel; - this.motor1.setAcceleration(acceleration); - this.motor2.setAcceleration(acceleration); - this.motor3.setAcceleration(acceleration); - } - - @Override - public double getLinearAcceleration() { - return acceleration; - } - - - - /** - * Start motors. - */ - private synchronized void startMotors() { - if (motor1Speed>0) - motor1.forward(); - else - motor1.backward(); - if (motor2Speed>0) - motor2.forward(); - else motor2.backward(); - if (motor3Speed>0) - motor3.forward(); - else motor3.backward(); - } - - /** - * Coast. TODO: Probably delete this method? - */ - private synchronized void coast() { - motor1.flt(); - motor2.flt(); - motor3.flt(); - spinningMode = false; - } - - public synchronized void forward() { - spinningMode = false; - setSpeed(linearSpeed, 0, angularSpeed); - startMotors(); - } - - public synchronized void backward() { - spinningMode = false; - setSpeed(linearSpeed, 180, angularSpeed); - startMotors(); - } - - /** - * This method causes the robot to move in a direction while keeping the front of the robot pointed in the current direction it is facing. - * - * @param linSpeed the lin speed - * @param direction the direction relative to the current direction the robot is facing - */ - public synchronized void moveStraight(float linSpeed, int direction) { -// float dir = linSpeed>0? direction : direction+180; - spinningMode = false; - setSpeed(linSpeed, direction, 0); - startMotors(); - } - - /** - * Causes the robot to spin while moving along a linear path. This method is similar to {@link OmniPilot#moveStraight(float, int)} - * except the robot will spin instead of holding the robot in the current direction. - * - * @param linSpeed the linear speed [units/s] - * @param angSpeed the angular speed [deg/s] - * @param direction the direction [deg] - */ - public synchronized void spinningMove(float linSpeed, int angSpeed, int direction) { - spinLinSpeed = linSpeed; - spinAngSpeed = angSpeed; - spinTravelDirection = direction; - spinningMode = true; -// setSpeed(spinLinSpeed, spinTravelDirection-pose.getHeading(), spinAngSpeed); -// startMotors(); - } - - public synchronized void stop() { - motor1.stop(); - motor2.stop(); - motor3.stop(); - spinningMode = false; - } - - public boolean isMoving() { - return motor1.isMoving() || motor2.isMoving() || motor3.isMoving(); - } - - public void setLinearSpeed(double speed) { - linearSpeed = Math.abs((float)speed); - reverse = speed<0; - } - - public double getLinearSpeed() { - return linearSpeed; - } - - /** - * Sets the move direction. This value is then used by subsequent calls to {@link OmniPilot#steer(float)} (all three overloaded methods). - * - * @param dir the new move direction - */ - public void setMoveDirection(int dir) { - speedVectorDirection = dir; - } - - /** - * Gets the move direction. - * - * @return the move direction - */ - public float getMoveDirection() { - return speedVectorDirection; - } - - public double getMaxLinearSpeed() { - // it is generally assumed, that the maximum accurate speed of Motor is - // 100 degree/second * Voltage - double maxRadSec = Math.toRadians(battery.getVoltage()*100f); - double[] spd = {0, maxRadSec, -maxRadSec}; - Matrix wheelSpeeds = new Matrix(spd, 3); - Matrix robotSpeeds = kMatrix.times(wheelSpeeds); - return (float) Math.sqrt(robotSpeeds.get(0,0)*robotSpeeds.get(0,0) + - robotSpeeds.get(1,0)*robotSpeeds.get(1,0)); - // max degree/second divided by degree/unit = unit/second - } - - public void setAngularSpeed(double speed) { - angularSpeed = (float)speed; - } - - public double getAngularSpeed() { - return angularSpeed; - } - - public double getMaxAngularSpeed() { - // it is generally assumed, that the maximum accurate speed of Motor is - // 100 degree/second * Voltage - double maxRadSec = Math.toRadians(battery.getVoltage()*100f); - Matrix wheelSpeeds = new Matrix(3, 1, maxRadSec); - Matrix robotSpeeds = kMatrix.times(wheelSpeeds); - return (float) Math.abs(Math.toDegrees(robotSpeeds.get(2,0))); - // max degree/second divided by degree/unit = unit/second - } - - private Move.MoveType previousMoveType = null; - private float previousDistance = 0; - private float previousAngle = 0; - - /** - * Move. - * - * @param distance the distance - * @param direction the direction - * @param angle the angle - * @param immediateReturn the immediate return - */ - private void move(final double distance, double direction, final double angle, boolean immediateReturn) { - // Notify MoveListeners that a new move has begun. - - if(distance != 0 & angle == 0) previousMoveType = Move.MoveType.TRAVEL; - else if(distance == 0 & angle != 0) previousMoveType = Move.MoveType.ROTATE; - else if(distance != 0 & angle != 0) previousMoveType = Move.MoveType.ARC; - else previousMoveType = Move.MoveType.STOP; - - for(MoveListener ml:listeners) - ml.moveStarted(new Move(previousMoveType, (float)distance, (float)angle, true), this); - - spinningMode = false; - double[] dsp = {distance*Math.cos(Math.toRadians(direction)), distance*Math.sin(Math.toRadians(direction)), Math.toRadians(angle)}; - Matrix displacement = new Matrix(dsp, 3); - Matrix distances = ikMatrix.times(displacement); - int d1 = (int) Math.toDegrees(distances.get(0,0)); - int d2 = (int) Math.toDegrees(distances.get(1,0)); - int d3 = (int) Math.toDegrees(distances.get(2,0)); - - if (angle==0) { - setSpeed(linearSpeed, direction, 0); - } - if (distance==0) { - setSpeed(0, 0, angularSpeed); - } -// LCD.drawString("dx "+(float)dsp[0]+" ", 0, 0); -// LCD.drawString("dy "+(float)dsp[1]+" ", 0, 1); -// LCD.drawString("d1 "+d1+" deg ", 0, 3); -// LCD.drawString("d2 "+d2+" deg ", 0, 4); -// LCD.drawString("d3 "+d3+" deg ", 0, 5); -// Button.waitForPress(); - motor1.rotate(d1, true); - motor2.rotate(d2, true); - motor3.rotate(d3, immediateReturn); - - if (!immediateReturn) - while (isMoving()) - Thread.yield(); - } - - public void travel(double distance) { - travel(distance, 0, false); - } - - /** - * This method causes the robot to travel in a linear path, similar to other travel() methods, except you can specify - * which direction to move (relative to the current robot heading). - * - * NOTE: This method is not part of the MoveController interface. - * @param distance - * @param direction - */ - public void travel(double distance, double direction) { - travel(distance, direction, false); - } - - public void travel(double distance, boolean immediateReturn) { - travel(distance, 0, immediateReturn); - } - - /** - * This method causes the robot to travel in a linear path, similar to other travel() methods, except you can specify - * which direction to move (relative to the current robot heading). - * - * NOTE: This method is not part of the MoveController interface. - * @param distance - * @param direction - * @param immediateReturn - */ - public void travel(double distance, double direction, boolean immediateReturn) { - move(distance, direction, 0, immediateReturn); - } - - public void rotate(double angle) { - rotate(angle, false); - } - - public void rotate(double angle, boolean immediateReturn) { - if (angularSpeed==0) angularSpeed = 90; - move(0, 0, angle, immediateReturn); - } - - - /** - * Gets the angle. - * - * @return the angle - */ - private float getAngle() { -// Sound.playTone(2000, 10); - int t1 = motor1.getTachoCount(); - int t2 = motor2.getTachoCount(); - int t3 = motor3.getTachoCount(); - double[] dsp = {Math.toRadians(t1),Math.toRadians(t2),Math.toRadians(t3)}; - Matrix displacement = new Matrix(dsp, 3); - Matrix distances = kMatrix.times(displacement); - float ang = (float) Math.toDegrees(distances.get(2,0)); -// LCD.drawString(t1+" "+t2+" "+t3, 0, 5); -// LCD.drawString("a "+ang+" ", 0, 6); - return ang; - } - - /** - * Gets the travel distance since last tacho reset. - * - * @return the travel distance - */ - private float getTravelDistance() { - int t1 = motor1.getTachoCount(); - int t2 = motor2.getTachoCount(); - int t3 = motor3.getTachoCount(); - double[] dsp = {Math.toRadians(t1),Math.toRadians(t2),Math.toRadians(t3)}; - Matrix displacement = new Matrix(dsp, 3); - Matrix distances = kMatrix.times(displacement); - float d = (float) Math.sqrt(distances.get(0,0)*distances.get(0,0) + distances.get(1,0)*distances.get(1,0)); //TODO is this correct for omni odometry? -// LCD.drawString(t1+" "+t2+" "+t3+" ", 0, 5); -// LCD.drawString("d "+d+" ", 0, 7); - return d; - } - - /** - * Steer. - * - * @param turnRate the turn rate - */ - public void steer(float turnRate) { - float angSpeed = (float)(turnRate*getMaxAngularSpeed()/200); - float dir = reverse? speedVectorDirection : speedVectorDirection+180; - spinningMode = false; - setSpeed(linearSpeed, dir, angSpeed); - startMotors(); - } - - /** - * Steer. - * - * @param linSpeed the lin speed - * @param angSpeed the ang speed - */ - public void steer(float linSpeed, float angSpeed) { -// float dir = linSpeed>0? speedVectorDirection : speedVectorDirection+180; - spinningMode = false; - setSpeed(linSpeed, speedVectorDirection, angSpeed); - startMotors(); - } - - /** - * Steer. - * - * @param turnRate the turn rate - * @param angle the angle - * @param immediateReturn the immediate return - */ - public void steer(float turnRate, float angle, boolean immediateReturn) { - angularSpeed = (float)(turnRate*getMaxAngularSpeed()/200); -// LCD.drawString("spd "+angularSpeed+" deg/s ", 0, 0); - float radius = (float) (linearSpeed/Math.toRadians(angularSpeed)); - arc(radius,angle,immediateReturn); - } - - public void travelArc(double radius, double distance) { - travelArc(radius, distance, false); - } - - public void travelArc(double radius, double distance, boolean immediateReturn) { - travelArc(radius, distance, 0, false); - } - - /** - * This method moves the robot in an arc, similar to the other {@link OmniPilot#travelArc(double, double)} methods, - * except you can choose any of the 360 degree directions relative to the current heading (0) of the robot, while keeping - * the heading of the robot pointed in the same direction during the move. - * - * NOTE: This method is not part of the MoveController interface. - * @param radius - * @param distance - * @param direction - */ - public void travelArc(double radius, double distance, float direction) { - travelArc(radius, distance, direction, false); - } - - /** - * This method moves the robot in an arc, similar to the other {@link OmniPilot#travelArc(double, double)} methods, - * except you can choose any of the 360 degree directions relative to the current heading (0) of the robot, while keeping - * the heading of the robot pointed in the same direction during the move. - * - * NOTE: This method is not part of the MoveController interface. - * @param radius - * @param distance - * @param direction - * @param immediateReturn - */ - public void travelArc(double radius, double distance, float direction, boolean immediateReturn) { - float angle = (float) ((distance * 180) / (Math.PI * radius)); - arc(radius, angle, direction, immediateReturn); - } - - public void arc(double radius, double angle) { - arc(radius, angle, 0, false); - } - - /** - * This method moves the robot in an arc, similar to the other {@link OmniPilot#arc(double, double)} methods, - * except you can choose any of the 360 degree directions relative to the current heading (0) of the robot, while keeping - * the heading of the robot pointed in the same direction during the move. - * - * NOTE: This method is not part of the MoveController interface. - * @param radius - * @param angle - * @param direction - */ - public void arc(double radius, double angle, double direction) { - arc(radius, angle, direction, false); - } - - public void arc(double radius, double angle, boolean immediateReturn) { - arc(radius,angle,0,immediateReturn); - } - - /** - * This method moves the robot in an arc, similar to the other {@link OmniPilot#arc(double, double)} methods, - * except you can choose any of the 360 degree directions relative to the current heading (0) of the robot, while keeping - * the heading of the robot pointed in the same direction during the move. - * - * NOTE: This method is not part of the MoveController interface. - * @param radius - * @param angle - * @param direction - * @param immediateReturn - */ - public void arc(double radius, double angle, double direction, boolean immediateReturn) { - - float angSpeed = (float) Math.toDegrees(linearSpeed/radius); - spinningMode = false; - setSpeed(linearSpeed, direction, angSpeed); - if (Float.isInfinite((float)angle)) { - startMotors(); - } else { - float distance = (float) (Math.toRadians(angle)*radius); -// LCD.drawString("R "+radius+" units ", 0, 0); -// LCD.drawString("A "+angle+" deg ", 0, 1); -// LCD.drawString("D "+distance+" units ", 0, 2); -// Button.waitForPress(); - move(distance,direction, angle, immediateReturn); - } - } - - - /** - * Reset all tacho counts. TODO: Delete this method? Unused by any other method or class. - */ - public void reset() { - motor1.resetTachoCount(); - motor2.resetTachoCount(); - motor3.resetTachoCount(); - odo.reset(); - } - - /** - * Sets drive motor speed. - * - * @param speed the new speed - * @deprecated in 0.8, use setRotateSpeed() and setTravelSpeed(). The method was deprecated, as this it requires knowledge - * of the robots physical construction, which this interface should hide! - */ - @Deprecated - public void setSpeed(int speed) { - setLinearSpeed(speed); - } - - private class Odometer extends Thread { - - private int t1old = 0; - - private int t2old = 0; - - private int t3old = 0; - - private boolean keepRunning = true; - - private int period = 10; //ms - - //private boolean displayPose = false; - - //private int displayLine = 0; - - /** - * Stop the odometry thread. - */ - public void shutDown() { - keepRunning = false; - } - - @Override - public void run() { - long tick = period + System.currentTimeMillis(); - while(keepRunning) { - if(System.currentTimeMillis()>= tick) { // simulate timer - tick += period; - updatePose(); - if (gyroEnabled) { - pose.setHeading(gyro.getAngle()/100.0f); - } - if (spinningMode) { - setSpeed(spinLinSpeed, spinTravelDirection-pose.getHeading(), spinAngSpeed); - startMotors(); - //LCD.drawString("t:"+tick, 0, 0); - } - } else { - Delay.msDelay(5); - } - } - } - - /** - * Reset odometry. - */ - public void reset() { - synchronized (pose) { - pose.setLocation(new Point(0, 0)); - pose.setHeading(0); - gyro.reset(); - } - } - - private void updatePose() - { -// Sound.playTone(1000, 5); - int t1 = motor1.getTachoCount(); - int t2 = motor2.getTachoCount(); - int t3 = motor3.getTachoCount(); - double[] angles = {Math.toRadians(t1-t1old),Math.toRadians(t2-t2old),Math.toRadians(t3-t3old)}; - Matrix wheelTachos = new Matrix(angles, 3); - Matrix localDeltaPose = kMatrix.times(wheelTachos); - float dXL = (float) localDeltaPose.get(0,0); - float dYL = (float) localDeltaPose.get(1,0); - float dH = (float) localDeltaPose.get(2,0); - - - float H = (float) Math.toRadians(pose.getHeading()); - float dX = (float) (Math.cos(H)*dXL - Math.sin(H)*dYL); - float dY = (float) (Math.sin(H)*dXL + Math.cos(H)*dYL); - pose.translate(dX, dY); - pose.rotateUpdate((float)Math.toDegrees(dH)); - t1old = t1; - t2old = t2; - t3old = t3; - /* - if (displayPose) { - LCD.drawString("X: "+ Math.round(pose.getX()*1000f)/1000f+ " ", 0, displayLine); - LCD.drawString("Y: "+ Math.round(pose.getY()*1000f)/1000f+ " ", 0, displayLine+1); - LCD.drawString("H: "+ Math.round(pose.getHeading()*1000f)/1000f+ " deg ", 0, displayLine+2); - }*/ - } - } - - - public void arcBackward(double radius) { - arc(radius, Double.NEGATIVE_INFINITY, true); - } - - public void arcForward(double radius) { - arc(radius, Double.POSITIVE_INFINITY, true); - } - - public double getMinRadius() { - return minTurnRadius; - } - - public void setMinRadius(double radius) { - minTurnRadius = radius; - } - - public void addMoveListener(MoveListener listener) { - listeners.add(listener); - } - - public Move getMovement() { - return new Move(previousMoveType, getTravelDistance() - previousDistance, getAngle() - previousAngle, isMoving()); - } - - public void rotationStarted(RegulatedMotor motor, int tachoCount, boolean stalled, long timeStamp) { - // Do nothing. private move() method handles notifications. - } - - /** - * Notify the MoveListeners when a move is completed. - */ - public void rotationStopped(RegulatedMotor motor, int tachoCount, boolean stalled, long timeStamp) { - if(!motor1.isMoving() && !motor2.isMoving() && !motor3.isMoving()) { - float newDistance = getTravelDistance(); - float newAngle = getAngle(); - Move finalMove = new Move(previousMoveType, newDistance - previousDistance, newAngle - previousAngle, isMoving()); - for(MoveListener ml:listeners) - ml.moveStopped(finalMove, this); - - //this.reset(); // THIS CAUSES AN EXCEPTION. Will subtract previous values instead. - previousDistance = newDistance; - previousAngle = newAngle; - } - } - - @Override - public void rotateRight() { - rotate(Double.NEGATIVE_INFINITY, true); - } - - @Override - public void rotateLeft() { - rotate(Double.POSITIVE_INFINITY, true); - } - - @Override - public void setAngularAcceleration(double acceleration) { - // TODO Pilot does not take angular acceleration into account. - // The method serves as a placeholder to satisfy the interface. - - - } - - @Override - public double getAngularAcceleration() { - // TODO see setAngularAcceleration - return 0; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/Pose.java b/ev3classes/src/main/java/lejos/robotics/navigation/Pose.java deleted file mode 100644 index 10e9164..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/Pose.java +++ /dev/null @@ -1,225 +0,0 @@ -package lejos.robotics.navigation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import lejos.robotics.Transmittable; -import lejos.robotics.geometry.Point; - -/** - * Represents the location and heading(direction angle) of a robot.
    - * This class includes methods for updating the Pose to in response to basic robot - * movements. - * It also contains utility methods for use in navigation, such as the - * direction and distance to a point from the location of the pose, and also the - * location of a point at a given distance and direction from the location of the pose.
    - * All directions and angles are in degrees and use the standard convention - * in mathematics: direction 0 is parallel to the X axis, and direction +90 is - * parallel to the Y axis.
    - * @author Roger Glassey - */ -public class Pose implements Transmittable -{ - /** - * allocate a new Pose at the origin, heading = 0:the direction the positive X axis - */ -public Pose() -{ - _location = new Point(0,0); - _heading = 0; -} -/** - * Allocate a new pose at location (x,y) with specified heading in degrees. - * - * @param x the X coordinate - * @param y the Y coordinate - * @param heading the heading - */ -public Pose(float x, float y, float heading) -{ - _location = new Point(x,y); - _heading = heading; -} -/** - * Rotate the heading through the specified angle - * - * @param angle - */ -public void rotateUpdate(float angle) -{ - _heading += angle; - while(_heading < 180)_heading += 360; - while(_heading > 180)_heading -= 360; -} - -/** - * Move the specified distance in the direction of current heading. - * - * @param distance to move - */ -public void moveUpdate(float distance) -{ - float x = distance * (float)Math.cos(Math.toRadians(_heading)); - float y = distance * (float)Math.sin(Math.toRadians(_heading)); - _location.translate(x,y); -} -/** - * Change the x and y coordinates of the pose by adding dx and dy. - * - * @param dx change in x coordinate - * @param dy change in y coordinate - */ -public void translate( float dx, float dy) -{ - _location.translate(dx,dy); -} -/** - * Sets the pose location and heading to the correct values resulting from travel - * in a circular arc. The radius is calculated from the distance and turn angle - * - * @param distance the distance traveled - * @param turnAngle the angle turned - */ -public void arcUpdate(float distance, float turnAngle) -{ - float dx = 0; - float dy = 0; - double heading = (Math.toRadians(_heading)); - if (Math.abs(turnAngle) > .5) - { - float turn = (float) Math.toRadians(turnAngle); - float radius = distance / turn; - dy = radius * (float) (Math.cos(heading) - Math.cos(heading + turn)); - dx = radius * (float) (Math.sin(heading + turn) - Math.sin(heading)); - } else if (Math.abs(distance) > .01) - { - dx = distance * (float) Math.cos(heading); - dy = distance * (float) Math.sin(heading); - } - _location.translate( dx, dy); - rotateUpdate(turnAngle); -} -/** - * Returns the angle with respect to the X axis to from the - * current location of this pose. - * @param destination - * @return angle in degrees - */ -public float angleTo(Point destination) -{ - return _location.angleTo(destination); -} -/** - * Returns the angle to destination relative to the pose heading; - * @param destination the target point - * @return the relative bearing of the destination, between -180 and 180 - */ -public float relativeBearing(Point destination) -{ - float bearing = angleTo(destination) - _heading; - if(bearing < -180)bearing +=360; - if(bearing > 180)bearing -= 360; - return bearing; -} -/** - * Return the distance to the destination - - * @param destination - * @return the distance - */ -public float distanceTo(Point destination) -{ - return (float) _location.distance(destination); -} -/** - * Returns the point at distance from the location of this pose, - * in the direction bearing relative to the X axis. - * @param distance the distance to the point - * @param bearing the true bearing of the point - * @return point - */ -public Point pointAt(float distance, float bearing) -{ - return _location.pointAt(distance, bearing); -} - -/** - * returns the heading (direction angle) of the Pose - * - * @return the heading - */ -public float getHeading() { return _heading ; } -/** - * Get the X coordinate - * - * @return the X coordinate - */ -public float getX(){ return (float) _location.getX();} -/** - * Get the Y coordinate - * - * @return the Y coordinate - */ -public float getY() {return (float)_location.getY();} - -/** - * Get the location as a Point - * - * @return the location as a point - */ -//TODO: Maybe call it getPoint()? -public Point getLocation() { return _location;} - -/** - * Set the location of the pose - * - * @param p the new location - */ -public void setLocation(Point p) -{ - _location = p; -} - -/** - * Sets the location of this pose to a new point at x,y; - * @param x - * @param y - */ -public void setLocation(float x, float y) -{ - setLocation(new Point(x,y)); -} - -public void setHeading(float heading ) -{ - _heading = heading; -} -/** - * return string contains x,y and heading - * @return x,y,heading - */ -@Override -public String toString() -{ - return String.format(format, _location.x, _location.y, _heading); -} - -public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeFloat(_location.x); - dos.writeFloat(_location.y); - dos.writeFloat(_heading); - dos.flush(); -} - -public void loadObject(DataInputStream dis) throws IOException { - _location = new Point(dis.readFloat(), dis.readFloat()); - _heading = dis.readFloat(); -} - -protected Point _location; -protected float _heading; -protected static String format ="X:%.0f Y:%.0f H:%.0f"; - -} - diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/RotateMoveController.java b/ev3classes/src/main/java/lejos/robotics/navigation/RotateMoveController.java deleted file mode 100644 index d4eb93a..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/RotateMoveController.java +++ /dev/null @@ -1,54 +0,0 @@ -package lejos.robotics.navigation; - -public interface RotateMoveController extends MoveController { - /** - * Rotates the NXT robot the specified number of degrees; direction determined by the sign of the parameter. - * Method returns when rotation is done. - * - * @param angle The angle to rotate in degrees. A positive value rotates left, a negative value right (clockwise). - */ - public void rotate(double angle); - /** - * Rotates the NXT robot the specified number of degrees; direction determined by the sign of the parameter. - * Method returns immediately if immediateReturn flag is true, otherwise returns when rotation is done. - * @param angle The angle to rotate in degrees. A positive value rotates left, a negative value right (clockwise). - * @param immediateReturn If true, method returns immediately, otherwise blocks until rotation is complete. - */ - public void rotate(double angle, boolean immediateReturn); - /** - * sets the rotation speed of the robot (the angular velocity of the rotate() - * methods) - * @param speed in degrees per second - */ - public void setAngularSpeed(double speed); - - /** - * Returns the value of the rotation speed - * @return the rotate speed in degrees per second - */ - public double getAngularSpeed(); - - /** - * returns the maximum value of the rotation speed; - * @return max rotation speed - */ - public double getMaxAngularSpeed(); - - /** - * Sets the acceleration at which the robot will accelerate at the start of a move and decelerate at the end of a move. - * Acceleration is measured in units/second^2. e.g. If wheel diameter is cm, then acceleration is cm/sec^2.

    - * If acceleration is set during a move it will not be in used for the current move, it will be in effect with the next move. - * @param acceleration in chosen units/second^2 - */ - public void setAngularAcceleration(double acceleration); - - /** Returns the acceleration at which the robot accelerates at the start of a move and decelerates at the end of a move. - * @return acceleration in chosen units/second^2 - */ - public double getAngularAcceleration(); - -public void rotateRight(); - -public void rotateLeft(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/SteeringPilot.java b/ev3classes/src/main/java/lejos/robotics/navigation/SteeringPilot.java deleted file mode 100644 index ab36c0e..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/SteeringPilot.java +++ /dev/null @@ -1,358 +0,0 @@ -package lejos.robotics.navigation; - -import lejos.robotics.RegulatedMotor; -import lejos.robotics.RegulatedMotorListener; - -/* - * DEV NOTES: Should add an optional method to auto-calibrate the steering. With low power, rotate steering all - * the way to the left and record tacho limit, then all the way to the right and record tacho limit. Assumes - * symmetrical steering values and estimates straight tacho value as average of two tacho counts. Make alternate - * constructor that doesn't use leftTacho and rightTacho values but calls auto calibrate method. - */ - -// TODO: Wikipedia article on Homotopy principle has some ideas about calculating position and steering of vehicle: -// http://en.wikipedia.org/wiki/Homotopy_principle#A_car_in_the_plane -// EQUATION: x sin A = y cos A -// where angle A describes orientation of the car - -/** - *

    Vehicles that are controlled by the SteeringPilot class use a similar steering mechanism to a car, in which the - * front wheels pivot from side to side to control direction.

    - * - *

    If you issue a command for travel(1000) and then issue a command travel(-500) before - * it completes the travel(1000) movement, it will call stop, properly inform movement listeners that - * the forward movement was halted, and then start moving backward 500 units. This makes movements from the SteeringPilot - * leak-proof and incorruptible.

    - * - *

    Note: A DifferentialPilot robot can simulate a SteeringPilot robot by calling {@link DifferentialPilot#setMinRadius(double)} - * and setting the value to something greater than zero (example: 15 cm).

    - * - * @see lejos.robotics.navigation.DifferentialPilot#setMinRadius(double) - * @author BB - * - */ -public class SteeringPilot implements ArcMoveController, RegulatedMotorListener { - - private lejos.robotics.RegulatedMotor driveMotor; - private lejos.robotics.RegulatedMotor steeringMotor; - private double minTurnRadius; - private double driveWheelDiameter; - - private boolean isMoving; - private int oldTacho; - - /** - * Rotate motor to this tacho value in order to achieve minimum left hand turn. - */ - private int minLeft; - - /** - * Rotate motor to this tacho value in order to achieve minimum right hand turn. - */ - private int minRight; - - /** - * Indicates the type of movement (arc, travel) that vehicle is engaged in. - */ - private Move moveEvent = null; - - // TODO: Possibly will need to allow multiple listeners - private MoveListener listener = null; - - /** - *

    Creates an instance of the SteeringPilot. The drive wheel measurements are written on the side of the LEGO tire, such - * as 56 x 26 (= 56 mm or 5.6 centimeters).

    - * - * The accuracy of this class is dependent on physical factors: - *
  • the surface the vehicle is driving on (hard smooth surfaces are much better than carpet) - *
  • the accuracy of the steering vehicle (backlash in the steering mechanism will cause turn-angle accuracy problems) - *
  • the ability of the steering robot to drive straight (if you see your robot trying to drive straight and it is driving - * a curve instead, accuracy will be thrown off significantly) - *
  • When using SteeringPilot with ArcPoseController, the starting position of the robot is also important. Is it truly - * lined up with the x axis? Are your destination targets on the floor accurately measured? - * - *

    Note: If your drive motor is geared for faster movement, you must multiply the wheel size by the - * gear ratio. e.g. If gear ratio is 3:1, multiply wheel diameter by 3. If your drive motor is geared for - * slower movement, divide wheel size by gear ratio.

    - * * - * @param driveWheelDiameter The diameter of the wheel(s) used to propel the vehicle. - * @param driveMotor The motor used to propel the vehicle, such as Motor.B - * @param steeringMotor The motor used to steer the steering wheels, such as Motor.C - * @param minTurnRadius The smallest turning radius the vehicle can turn. e.g. 41 centimeters - * @param leftTurnTacho The tachometer the steering motor must turn to in order to turn left with the minimum turn radius. - * @param rightTurnTacho The tachometer the steering motor must turn to in order to turn right with the minimum turn radius. - */ - public SteeringPilot(double driveWheelDiameter, lejos.robotics.RegulatedMotor driveMotor, - lejos.robotics.RegulatedMotor steeringMotor, double minTurnRadius, int leftTurnTacho, int rightTurnTacho) { - this.driveMotor = driveMotor; - this.steeringMotor = steeringMotor; - this.driveMotor.addListener(this); - this.driveWheelDiameter = driveWheelDiameter; - this.minTurnRadius = minTurnRadius; - this.minLeft = leftTurnTacho; - this.minRight = rightTurnTacho; - - this.isMoving = false; - } - - /** - *

    This method calibrates the steering mechanism by turning the wheels all the way to the right and - * left until they encounter resistance and recording the tachometer values. These values determine the - * outer bounds of steering. The center steering value is the average of the two. NOTE: This method only - * works with steering robots that are symmetrical (same maximum steering threshold left and right).

    - * - * TODO: Should be able to get steering parity right from this class! No need to fish for boolean. - *

    When you run the method, if you notice the wheels turn left first, then right, it means you need - * to set the reverse parameter to true for proper calibration. NOTE: The next time you run the calibrate - * method it will still turn left first, but...

    - */ - public void calibrateSteering() { - - // TODO: Not really necessary to check for stall. Could just rotate for about 2 seconds and take a tacho reading. - // This would help with RemoteMotor and remote SteeringPilot, which doesn't implement isStalled(). - - steeringMotor.setSpeed(100); - steeringMotor.setStallThreshold(10, 100); - - steeringMotor.forward(); - while(!steeringMotor.isStalled()) Thread.yield(); - int r = steeringMotor.getTachoCount(); - - steeringMotor.backward(); - try { - Thread.sleep(200); - } catch (InterruptedException e) { - e.printStackTrace(); - } - while(!steeringMotor.isStalled()) Thread.yield(); - int l = steeringMotor.getTachoCount(); - - int center = (l + r) / 2; // TODO: Maybe reset tacho to zero? Seems like there is no center variable. - - /* - System.out.println("Left " + l); - System.out.println("Right " + r); - System.out.println("Center " + center); - */ - - // Adjust values so they are still meaningful when tachocount is reset to zero below (0 = center): - r -= center; - l -= center; - /* System.out.println("LEFT " + l); - System.out.println("RIGHT " + r); */ - - minRight = r; - minLeft = l; - - // TODO: I'm not sure if reverse steering works yet with actual SteeringPilot class. - - /* TODO: I'm not totally satisfied with this final step in calibration. It invariably doesn't quite rotate - * to the center value (off by one) and then all subsequent center positions are off by one degree. Would - * rather store the center/left/right values and use them, but this class wasn't programmed that way with - * calibration and values in mind. - */ - steeringMotor.rotateTo(center); - // System.out.println("CENTER:" + steeringMotor.getTachoCount()); - steeringMotor.resetTachoCount(); - //steeringMotor.flt(); - steeringMotor.setStallThreshold(50,1000); // Reset to defaults. - } - - /** - * In practice, a robot might steer tighter with one turn than the other. - * Currently returns minimum steering radius for the least tight turn direction. - * @return minimum turning radius, in centimeters - */ - public double getMinRadius() { - return minTurnRadius; - } - - // NOTE: Currently the steer method locks this SteeringPilot into one proprietary LEGO robot design. - // Tach values for left and right should be in constructor. - // Should be able to use this class with a variety of steering robots. - // NOTE: Doesn't actually have variable turn radius. Just minTurnRadius for now. - // Note: Perhaps it should return the actual radius/arc it achieves, in case can't do the one it is called to do. - // Although this might really screw things up for the algorithm. Shouldn't necessarily attempt arc it wasn't asked to perform. - // Perhaps it should check if radius is < minRadius, then throw exception or return failed if it can't do it. - /** - * Positive radius = left turn - * Negative radius = right turn - */ - private double steer(double radius) { - if(radius == Double.POSITIVE_INFINITY) { - this.steeringMotor.rotateTo(0); - return Double.POSITIVE_INFINITY; - } else if(radius > 0) { - this.steeringMotor.rotateTo(minLeft); - return getMinRadius(); - } else { // if(radius <= 0) - this.steeringMotor.rotateTo(minRight); - return -getMinRadius(); - } - } - - public void arcForward(double turnRadius) { - arc(turnRadius, Double.POSITIVE_INFINITY, true); - } - - public void arcBackward(double turnRadius) { - arc(turnRadius, Double.NEGATIVE_INFINITY, true); - } - - public void arc(double turnRadius, double arcAngle) throws IllegalArgumentException { - if(turnRadius == 0) throw new IllegalArgumentException("SteeringPilot can't do zero radius turns."); // Can't turn in one spot - arc(turnRadius, arcAngle, false); - } - - public void arc(double turnRadius, double arcAngle, boolean immediateReturn) { - double distance = Move.convertAngleToDistance((float)arcAngle, (float)turnRadius); - travelArc(turnRadius, (float)distance, immediateReturn); - } - - public void setMinRadius(double minTurnRadius) { - this.minTurnRadius = minTurnRadius; - } - - public void travelArc(double turnRadius, double distance) { - travelArc(turnRadius, distance, false); - } - - // TODO: Currently the DifferentialPilot goes forward if radius is negative. This goes backwards. - public void travelArc(double turnRadius, double distance, boolean immediateReturn) throws IllegalArgumentException { - - // Hack here because JVM causes extra decimals for Math.abs function? - double diff = this.getMinRadius() - Math.abs(turnRadius); - if(diff > 0.1) throw new IllegalArgumentException("Turn radius can't be less than " + this.getMinRadius()); - - // 1. Check if moving. If so, call stop. - if(isMoving) stop(); - - // 2. Change wheel steering: - double actualRadius = steer(turnRadius); - - // 3 Create new Move object: - double angle = Move.convertDistanceToAngle((float)distance, (float)actualRadius); - moveEvent = new Move((float)distance, (float)angle, true); - - - // TODO: This if() block is a temporary kludge due to Motor.rotate() bug with Integer.MIN_VALUE: - // Remove this if Roger changes Motor.rotate(). - if((distance == Double.NEGATIVE_INFINITY) | (distance == Double.POSITIVE_INFINITY)) { - driveMotor.backward(); - //return moveEvent; - } - - // 4. Start moving - // Convert Float infinity to Integer maximum value. - int tachos = (int)((distance * 360) / (driveWheelDiameter * Math.PI)); - driveMotor.rotate(tachos, immediateReturn); - - //return moveEvent; - } - - public void backward() { - travel(Double.NEGATIVE_INFINITY, true); - } - - public void forward() { - travel(Double.POSITIVE_INFINITY, true); - } - - public double getMaxLinearSpeed() { - // TODO Auto-generated method stub - return 0; - } - - // TODO: This method should indicate it is not live speed. Such as getSpeedSetting(), setSpeedSetting() - // TODO: Many methods in MoveController have no documentation and unit specification, incl. this. - public double getLinearSpeed() { - // TODO Auto-generated method stub - return 0; - } - - public float getMovementIncrement() { - // TODO Auto-generated method stub - return 0; - } - - public boolean isMoving() { - return isMoving; - } - - public void setLinearSpeed(double speed) { - // TODO This should set the motor speed for the drive motor, perhaps also calculates based on wheel diameter? - - } - - public void stop() { - // 1. Check if moving. If not, return? -// if(!isMoving()) return false; // Should return no movement? Or moveEvent? Null might be appropriate. - - // 2. Get instance of moveEvent here. Used to check when rotationStopped() completes - Move oldMove = moveEvent; - - // 3. Stop motor - driveMotor.stop(); - - // 4. Compare oldMove with moveEvent, only proceed when it changes - while(oldMove == moveEvent) {Thread.yield();} - - // 5. Return newly created moveEvent - //return moveEvent; - } - - public void travel(double distance) { - travel(distance, false); - } - - public void travel(double distance, boolean immediateReturn) { - travelArc(Double.POSITIVE_INFINITY, distance, immediateReturn); - } - - public void addMoveListener(MoveListener listener) { - this.listener = listener; - } - - public Move getMovement() { - // TODO This is probably supposed to provide the movement that has occurred since starting? (No Javadocs for this method makes it hard to figure out how to implement this method.) - return null; - } - - public void rotationStarted(RegulatedMotor motor, int tachoCount, boolean stall, long timeStamp) { - isMoving = true; - oldTacho = tachoCount; - - // Notify MoveListener - if(listener != null) { - listener.moveStarted(moveEvent, this); - } - } - - public void rotationStopped(RegulatedMotor motor, int tachoCount,boolean stall, long timeStamp) { - isMoving = false; - int tachoTotal = tachoCount - oldTacho ; - float distance = (float)((tachoTotal/360f) * Math.PI * driveWheelDiameter); - - float angle = Move.convertDistanceToAngle(distance, moveEvent.getArcRadius()); - - moveEvent = new Move(distance ,angle, isMoving); - - // Notify MoveListener - if(listener != null) { - listener.moveStopped(moveEvent, this); - } - - } - - @Override - public void setLinearAcceleration(double acceleration) { - // TODO: Added for interface, not in effect - - } - - @Override - public double getLinearAcceleration() { - // TODO: Added for interface, not in effect - return 0; - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/Waypoint.java b/ev3classes/src/main/java/lejos/robotics/navigation/Waypoint.java deleted file mode 100644 index 5293a8c..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/Waypoint.java +++ /dev/null @@ -1,108 +0,0 @@ -package lejos.robotics.navigation; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import lejos.robotics.Transmittable; -import lejos.robotics.geometry.Point; - -/** - * A sequence of way points make up a route that a robot can navigate. - * - * Waypoint extends Point, as a way point can just be a point. - * - * However, a Waypoint can optionally specify a heading that the robot must achieve when it reaches the way points. - * - * It can also optionally specify how close the robot must get to the way point in order for it to be deemed to - * have reached it. - * - */ -public class Waypoint extends Point implements Transmittable { - protected float heading = 0; - protected boolean headingRequired; - protected float maxPositionError = -1; - protected float maxHeadingError = -1; - - public Waypoint(double x, double y) { - super((float)x,(float)y); - headingRequired = false; - } - - public Waypoint(double x, double y, double heading) { - super((float)x,(float)y); - headingRequired = true; - this.heading = (float)heading; - } - - public Waypoint(Point p) { - super((float) p.getX(),(float) p.getY()); - headingRequired = false; - } - - public Waypoint(Pose p) { - super(p.getX(),p.getY()); - headingRequired = true; - this.heading = p.getHeading(); - } - - public double getHeading() { - return heading; - } - - public boolean isHeadingRequired() { - return headingRequired; - } - - public double getMaxPositionError() { - return maxPositionError; - } - - public void setMaxPositionError(double distance) { - maxPositionError = (float)distance; - } - - public double getMaxHeadingError() { - return maxHeadingError; - } - - public void setMaxHeadingError(double distance) { - maxHeadingError = (float)distance; - } - - /** - * Return a Pose that represents the way point. If no header is specified, it is set to zero. - * - * @return the pose corresponding to the way point - */ - public Pose getPose() { - return new Pose(x,y,heading); - } - - /** - * Check that the given pose satisfies the conditions for this way point - * @param p the Pose - */ - public boolean checkValidity(Pose p) { - if (maxPositionError >= 0 && - p.distanceTo(this) > maxPositionError) return false; - if (headingRequired && maxHeadingError >= 0 && - Math.abs(p.getHeading() - heading) > maxHeadingError) return false; - return true; - } - - public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeFloat(x); - dos.writeFloat(y); - dos.writeFloat(heading); - dos.writeBoolean(headingRequired); - dos.flush(); - } - - public void loadObject(DataInputStream dis) throws IOException { - x = dis.readFloat(); - y = dis.readFloat(); - heading = dis.readFloat(); - headingRequired = dis.readBoolean(); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/WaypointListener.java b/ev3classes/src/main/java/lejos/robotics/navigation/WaypointListener.java deleted file mode 100644 index 910a365..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/WaypointListener.java +++ /dev/null @@ -1,20 +0,0 @@ -package lejos.robotics.navigation; - -/** - * Interface for informing listeners that a way point has been generated. - * - */ -public interface WaypointListener -{ - /** - * Called when the class providing waypoints generates a new waypoint. - * @param wp the new waypoint - */ - public void addWaypoint(Waypoint wp); - - /** - * Called when generation of the path is complete - */ - public void pathGenerated(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/navigation/package-info.java b/ev3classes/src/main/java/lejos/robotics/navigation/package-info.java deleted file mode 100644 index 3ad6bb6..0000000 --- a/ev3classes/src/main/java/lejos/robotics/navigation/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Navigation classes. - */ -package lejos.robotics.navigation; diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/Feature.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/Feature.java deleted file mode 100644 index 0112916..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/Feature.java +++ /dev/null @@ -1,39 +0,0 @@ -package lejos.robotics.objectdetection; - -import lejos.robotics.RangeReading; -import lejos.robotics.RangeReadings; - -/** - * A Feature is an interface for information retrieved about an object detected by - * sensors. Feature is a map feature that is detected and reported by a FeatureDetector. - * @author BB based on concepts by Lawrie Griffiths - */ -public interface Feature { - - // TODO: It's possible that a detector would detect the coordinate position of something, not - // really have the relative position to vehicle available. - - /** - * Returns the RangeReading for this particular detected feature. If the sensor is capable of detecting multiple - * objects, this method will return the closest object it detected. - * - * @return RangeReading object containing angle and range. - */ - public RangeReading getRangeReading(); - - /** - * Returns a set of RangeReadings for a number of detected objects. If the sensor is only capable of returning - * a single reading, or if only one object was detected, it will only contain one RangeReading in the set. - * - * @return RangeReadings object containing a set of RangeReading objects. - */ - public RangeReadings getRangeReadings(); - - /** - * The time-stamp is the recorded system time when the range reading was taken. This is generally - * recorded in the constructor of the Feature implementation. The time-stamp can help - * identify the vector of the detected object. - * @return The system time (in milliseconds) when the reading was taken. - */ - public long getTimeStamp(); -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetector.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetector.java deleted file mode 100644 index 873c2e7..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetector.java +++ /dev/null @@ -1,85 +0,0 @@ -package lejos.robotics.objectdetection; - -/* - * TODO: Testing: - * 1. See how code looks to make a range sensor proportionally rotate left or right when doing an arc. - * More of a move listener thing maybe, but needs to see the angle. - * 2. Implement a bumper navigator and echo navigator sample. - * 3. See how easy it is to react differently based on criteria (such as person ID - chase or run away depending on person). - * 4. Implement this API in PathPlanner/PathController. Will need setFeatureDetector() and alt constructor. - */ - -/** - *

    A FeatureDetector is capable of detecting objects and notifying listeners when it detects something. A Feature is - * a term for any property that can be added to map data. The FeatureListener is notified when an object is detected, - * even if it has previously detected the same object.

    - * - *

    The most basic feature is the Range Feature, which indicates the position of the detected object relative - * to the "center" of the robot (normally the point mid-way between the drive wheels). A robot with many bumpers - * arrayed around the robot will also report the bumper location relative to the robot center.

    - * - *

    There can be many different qualities recorded by different FeatureDetector implementations. For example, you could - * implement a VectorFeatureDetector that could take multiple readings of an object, determine any change in position, - * and return the velocity/vector of the object (provided the sensor is capable of identifying an object and change in - * position). For example, a camera could note the change in position of objects and estimate the vector/velocity of - * the object.

    - * - *

    Note: Because {@link FeatureListener#featureDetected(Feature, FeatureDetector)} and {@link FeatureDetector#scan()} are - * only capable of returning a Feature object, any classes that want to read extended feature qualities (e.g. - * vector, color, or person data) would need to use an instanceof test to see if it is the appropriate data container, - * then cast the object into that type in order to retrieve the unique data.

    - * - * @see lejos.robotics.objectdetection.FeatureListener - * @author BB based on concepts by Lawrie Griffiths - * - */ -public interface FeatureDetector { - - /** - * Adds a listener to the FeatureDetector. The FeatureListener will be notified when objects are detected. - * - * @param listener The FeatureListener that is notified every time a feature is detected. - * - */ - public void addListener(FeatureListener listener); - - // TODO: Is null the best thing to return if it doesn't detect anything? - /** - *

    Performs a single scan for an object and returns the results. If an object is not detected, this - * method returns null.

    - *

    Warning: Make sure to check for a null object before trying to read data from the returned - * Feature object, otherwise your code will throw a null pointer exception.

    - * @return A feature it has detected. null if nothing found. - */ - public Feature scan(); - - /** - * Enable or disable detection of objects. - * - * @param on true enables detection and notifications, false disables this class until it is enabled again. - */ - public void enableDetection(boolean on); - - /** - * Indicates if automatic scanning mode and listener notification is currently enabled. (true by default) - * @return true if enabled, false if not - */ - public boolean isEnabled(); - - /** - * The minimum delay between notification of readings from the feature detector. If no objects are detected, - * no notification will occur. Some sensors, such as touch sensors, check the sensor more frequently than other - * sensors, such as range sensors. - * - * @return The delay between sensor readings. - */ - public int getDelay(); - - /** - * Sets the minimum delay between readings from the feature detector. The notification thread will notify - * FeatureListener objects every delay milliseconds, unless it takes longer to retrieve readings - * from the sensor. - * @param delay The FeatureDetector will return one new set of readings every delay milliseconds. - */ - public void setDelay(int delay); -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetectorAdapter.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetectorAdapter.java deleted file mode 100644 index d3e6a85..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureDetectorAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -package lejos.robotics.objectdetection; - -import java.util.ArrayList; - -/** - * An adapter to make it easier to implement FeatureDetector classes. The scan() method is the only method - * which must be implemented by the actual class. - * - * @author BB - * - */ -public abstract class FeatureDetectorAdapter implements FeatureDetector { - - private ArrayList listeners = null; - private boolean enabled = true; - private int delay = 0; - - public FeatureDetectorAdapter(int delay) { - this.delay = delay; - Thread x = new MonitorThread(); - x.setDaemon(true); - x.start(); - } - - public void addListener(FeatureListener l){ - if(listeners == null )listeners = new ArrayList(); - listeners.add(l); - } - - public void enableDetection(boolean enable) { - // TODO: Optionally do a real disable where it ends thread (true test in thread loop) and - // enabling it will start thread (if thread is null/not running). - this.enabled = enable; - } - - public boolean isEnabled() { - return enabled; - } - - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - /** - * Thread to monitor the range finder. - * - */ - private class MonitorThread extends Thread{ - - long prev_time; - - @Override - public void run() { - while(true) { - // Only performs scan if detection is enabled. - Feature f = (enabled?scan():null); - if(f != null) notifyListeners(f); - - try { - long elapsed_time = System.currentTimeMillis() - prev_time; - - - long actual_delay = delay - elapsed_time; - if(actual_delay < 0) actual_delay = 0; - - Thread.sleep(actual_delay); - prev_time = System.currentTimeMillis(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - } - - protected void notifyListeners(Feature feature) { - if(listeners != null) { - for(FeatureListener l : listeners) { - l.featureDetected(feature, this); - } - } - } - - public abstract Feature scan(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureListener.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureListener.java deleted file mode 100644 index e5ed6d2..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/FeatureListener.java +++ /dev/null @@ -1,18 +0,0 @@ -package lejos.robotics.objectdetection; - -/** - * Any class implementing this interface and registering with a FeatureDetector will receive - * notifications when a feature is detected. - * @see lejos.robotics.objectdetection.FeatureDetector#addListener(FeatureListener) - * @author BB based on concepts by Lawrie Griffiths - * - */ -public interface FeatureListener { - - /** - * The angle and range (in a RangeReading) of a feature is reported when a feature is detected. - * @param feature The RangeReading, which contains angle and range. - */ - public void featureDetected(Feature feature, FeatureDetector detector); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/FusorDetector.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/FusorDetector.java deleted file mode 100644 index 7ef8053..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/FusorDetector.java +++ /dev/null @@ -1,187 +0,0 @@ -package lejos.robotics.objectdetection; - -import java.util.ArrayList; - -import lejos.robotics.RangeReading; -import lejos.robotics.RangeReadings; - -/** - *

    If you have a robot with multiple sensors (touch and range) and would like them to report to one - * listener, or if you want to control them at the same time (such as disabling them all at once) you can - * use this class.

    - * - *

    This class maintains its own thread for checking the FeatureDetectors.

    - * - * @author BB - * - */ -public class FusorDetector implements FeatureDetector, FeatureListener { - // TODO: Make inner FeatureListener - - private ArrayList detectors = null; - - private ArrayList readings = null; - - /** - * The delay (in ms) between notifying listeners of detected features (if any are detected). - */ - private int delay; - - private boolean enabled = true; - - private ArrayList listeners = null; - - public FusorDetector() { - detectors = new ArrayList(); - readings = new ArrayList(); - - Thread x = new NotifyThread(); - x.setDaemon(true); - x.start(); - } - - /** - * This method adds another FeatureDetector to the FusorDetector. This method will set the delay - * for this class to the largest delay if comes across from all the FeatureDetector objects added - * to it. - * @param detector - */ - public void addDetector(FeatureDetector detector) { - // Add this class as a FeatureListener: - detector.addListener(this); - - // TODO: Does ArrayList already check if redundant objects are added? - if(!detectors.contains(detector)) detectors.add(detector); - - // Set delay to the largest delay it comes across: - if(detector.getDelay() > this.delay) - this.delay = detector.getDelay(); - readings.add(new RangeReadings(0)); // Add dummy object to expand size of RangeReadings - } - /** - * This method scans all the sensors added to this object and returns the amalgamated results. - * NOTE: This method is not called by the thread code. - */ - public Feature scan() { - RangeReadings rr = new RangeReadings(0); - for(FeatureDetector d : detectors) { - Feature df = d.scan(); - if(df != null) { - RangeReadings temp = df.getRangeReadings(); - for(int i=0;i 0) - notifyListeners(new RangeFeature(rrs)); - - // 4. Now clear out the detectors so they aren't resent next loop. - readings.clear(); - - // 5. And add dummies to it to make it proper size. - for(int i=0;i(); - this.listeners.add(listener); - } - - /** - * This method enables/disables automatic scanning and listener reporting for this object and - * all FeatureDetectors used in this FusorDetector object. - */ - public void enableDetection(boolean on) { - enabled = on; - for(FeatureDetector fd : detectors) { - fd.enableDetection(on); - } - } - - public int getDelay() { - return delay; - } - - public boolean isEnabled() { - return enabled; - } - - public void setDelay(int delay) { - this.delay = delay; - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeature.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeature.java deleted file mode 100644 index 8888e03..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeature.java +++ /dev/null @@ -1,109 +0,0 @@ -package lejos.robotics.objectdetection; - -/* - * - * DEVELOPER NOTES: This is a little weird because if you extend it to include say facial recognition information - * about the person it detected, with multiple facial detections the information need to be indexed separately - * from the RangeReading objects. - */ - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import lejos.robotics.RangeReading; -import lejos.robotics.RangeReadings; -import lejos.robotics.Transmittable; -import lejos.robotics.navigation.Pose; - -/** - *

    This class is a basic data container for information retrieved about an object detected by - * sensors. The RangeFeature contains only the most basic range information of a detected object, which - * is {@link RangeReading}. The RangeReading contains range and angle data relative to the robot.

    - * - *

    It can be extended to include more information, such as color. For example, a ColorFeature would - * rely on a ColorFeatureDetector to supply color information and range. The ColorFeatureDetector could extend - * FeatureDetector and accept a camera in the constructor to identify color of a detected object. This type of - * class would be useful to allow soccer robots to identify team-mates, the soccer ball, and the different goals.

    - * - * @author BB - * - */ -public class RangeFeature implements Feature, Transmittable { - - private RangeReading rr; - private RangeReadings rrs; - private long timeStamp; - private Pose pose = new Pose(0,0,0); - - /** - * Creates a RangeFeature containing a single RangeReading. If the {@link RangeFeature#getRangeReadings()} - * method is subsequently called, it will return a RangeReadings set containing only one RangeReading (rr). - * @param rr The RangeReading. - */ - public RangeFeature(RangeReading rr) { - timeStamp = System.currentTimeMillis(); - this.rr = rr; - } - - /** - * Creates a RangeFeature containing multiple RangeReadings. The {@link RangeFeature#getRangeReading()} method - * will return the RangeReading with the smallest range. - * - * @param rrs A (@link RangeReadings} object containing a set of {@link RangeReading} values. - */ - public RangeFeature(RangeReadings rrs) { - // TODO: This assumes index 0 is closest range. Should really check for the one with the shortest range. - // Might also want to make sure this is not empty. - this(rrs.get(0)); - this.rrs = rrs; - } - - /** - * Creates a RangeFeature containing multiple RangeReadings. The {@link RangeFeature#getRangeReading()} method - * will return the RangeReading with the smallest range. - * - * @param rrs A (@link RangeReadings} object containing a set of {@link RangeReading} values. - * @param pose the pose of the robot when the reading was taken - */ - public RangeFeature(RangeReadings rrs, Pose pose) { - // TODO: This assumes index 0 is closest range. Should really check for the one with the shortest range. - // Might also want to make sure this is not empty. - this(rrs.get(0)); - this.rrs = rrs; - this.pose = pose; - } - - public RangeReading getRangeReading() { - return rr; - } - - public long getTimeStamp() { - return timeStamp; - } - - public RangeReadings getRangeReadings() { - if(rrs == null) { - rrs = new RangeReadings(0); - rrs.add(rr); - } - return rrs; - } - - public Pose getPose() { - return pose; - } - - public void dumpObject(DataOutputStream dos) throws IOException { - pose.dumpObject(dos); - dos.writeFloat(rr.getRange()); - dos.writeLong(timeStamp); - dos.flush(); - } - - public void loadObject(DataInputStream dis) throws IOException { - pose.loadObject(dis); - float range = dis.readFloat(); - rr = new RangeReading(0f,range); - timeStamp = dis.readLong(); - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeatureDetector.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeatureDetector.java deleted file mode 100644 index 0044413..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/RangeFeatureDetector.java +++ /dev/null @@ -1,110 +0,0 @@ -package lejos.robotics.objectdetection; - -import lejos.robotics.RangeFinder; -import lejos.robotics.RangeReading; -import lejos.robotics.RangeReadings; -import lejos.robotics.localization.PoseProvider; - -/* - * DEVELOPER NOTES: - * TODO: Some of these API docs might be more appropriate in FeatureDetector - * TODO: One weakness of this class is it forces RangeFinder to use multiple readings. Might be some benefits to only - * retrieving one reading from ultrasonic sensor. - */ - -/** - *

    The RangeFeatureDetector used a RangeFinder to locate objects (known as features when mapping). This class is - * unable to identify the feature and merely reports the range and angle to the object.

    - * - *

    You can also have the scan identify the object (such as a camera using facial recognition to identify a person). - * One possibility to implement this is to extend RangeFeatureDetector and add a camera to the constructor. When the - * FeatureDetector range scanner detects an object, take a picture and look for a face in the image. This is then - * reported as an extended class of RangeFeature called PersonFeature, which has a getPerson() method containing - * information on the object that was detected.

    - * - *

    To create a more complex FeatureDetector, extend this class and override the {@link FeatureDetector#scan()} method. - * It is possible to add more complex functionality in this method, such as only returning a "hit" if the scanner detects - * an object in the same location twice in a row. This type of filtering could also take place in the FeatureListener - * method, although then single {@link FeatureDetector#scan()} calls will not contain the filtering.

    - * - * - * @author BB based on concepts by Lawrie Griffiths - * - */ -public class RangeFeatureDetector extends FeatureDetectorAdapter { - - private RangeFinder range_finder = null; - private float max_dist = 100; - private float angle = 0; - private PoseProvider pp = null; - - // TODO: Accept optional RangeScanner? - - // TODO: Alternate constructor for range sensors mounted non-center. - - /** - * This constructor allows you to specify the sensor, the maximum distance to report a - * detection, and the delay between scanning the sensor. It assumes the range sensor is - * pointed straight ahead, so heading is always 0 for the returned RangeReading. - * @param rf The range finder sensor. e.g. UltrasonicSensor - * @param maxDistance The upper limit of distance it will report. e.g. 40 cm. - * @param delay The interval range finder checks for objects. e.g. 250 ms. - */ - public RangeFeatureDetector(RangeFinder rf, float maxDistance, int delay) { - this(rf, maxDistance, delay, 0); - } - - - /** - * This constructor allows you to specify the sensor, the maximum distance to report a - * detection, the delay between scanning the sensor, and the angle the sensor is pointed. - * @param rf The range finder sensor. e.g. UltrasonicSensor - * @param maxDistance The upper limit of distance it will report. e.g. 40 cm. - * @param delay The interval range finder checks for objects. e.g. 250 ms. - * @param angle The angle, in degrees, the range sensor is pointed. (0 = forward, +ve = left, -ve = right) - */ - public RangeFeatureDetector(RangeFinder rf, float maxDistance, int delay, double angle) { - super(delay); - this.angle = (float)angle; - this.range_finder = rf; - setMaxDistance(maxDistance); - } - - - public void setPoseProvider(PoseProvider pp) { - this.pp = pp; - } - - /** - * Sets the maximum distance to register detected objects from the range finder. - * @param distance The maximum distance. e.g. 40 cm. - */ - public void setMaxDistance(float distance) { - this.max_dist = distance; - } - - /** - * Returns the maximum distance the FeatureDetector will return for detected objects. - * @return The maximum distance. e.g. 40 cm. - */ - public float getMaxDistance(){ - return this.max_dist; - } - - @Override - public Feature scan() { - RangeFeature feature = null; - // TODO: Note: If it is slower to retrieve multiple rather than single scan. Have option for single only in constructor? - float [] ranges = range_finder.getRanges(); - RangeReadings rrs = new RangeReadings(0); // TODO: Should it omit anything outside max_dist? - if(ranges.length <= 0) return null; // Check to make sure it retrieved some readings. Seems to return nothing sometimes. - if(ranges[0] > 0 & ranges[0] < max_dist) { - for(int i=0;i listeners = null; - - /** - * Creates a touch detector in which the touch sensor is assumed to be situated in the center of - * the robot. This is fine in situations where the robot only needs to react to a bumper - * contact. See the alternate constructor if more than one bumper is located around the robot. - * @param touchSensor The touch sensor bumper. - */ - public TouchFeatureDetector(Touch touchSensor) { - this(touchSensor, 0, 0); - } - - /** - * If you want the bumpers to report contact relative to the geometry of where they are placed on the robot, - * you can provide the x, y offsets of each bumper relative to the center of the robot (the center is - * the halfway point between the drive wheels). Most bumpers are planar, so generally you would use the center of - * the bumper as the contact point. - * - * @param touchSensor The touch sensor bumper. - * @param xOffset The offset (in units e.g. cm) left or right of center. Right is positive, left is negative. - * @param yOffset The offset (in units e.g. cm) forward or back of center. Forward is positive, back is negative. - */ - public TouchFeatureDetector(Touch touchSensor, double xOffset, double yOffset) { - // TODO: Probably better to accept distance and range value instead! Simpler, more consistent - - super(DELAY); - this.touch_sensor = touchSensor; - //this.x_offset = xOffset; - //this.y_offset = yOffset; - - // Calculate angle a distance of bumper from center: - Point robot_center = new Point(0, 0); - Point bumper_p = new Point((float)xOffset, (float)yOffset); - range = (float)robot_center.distance(xOffset, yOffset); - angle = robot_center.angleTo(bumper_p) - 90; - } - - public Feature scan() { - RangeFeature rf = null; - if(touch_sensor.isPressed()) { - RangeReading rr = new RangeReading(angle, range); - rf = new RangeFeature(rr); - } - return rf; - } - - @Override - protected void notifyListeners(Feature feature) { - super.notifyListeners(feature); - // Wait until bumper is released before continuing to prevent multiple notifications from same press: - while(touch_sensor.isPressed()); - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/objectdetection/package-info.java b/ev3classes/src/main/java/lejos/robotics/objectdetection/package-info.java deleted file mode 100644 index 0c93a73..0000000 --- a/ev3classes/src/main/java/lejos/robotics/objectdetection/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Object detection classes. - */ -package lejos.robotics.objectdetection; diff --git a/ev3classes/src/main/java/lejos/robotics/package-info.java b/ev3classes/src/main/java/lejos/robotics/package-info.java deleted file mode 100644 index 6073571..0000000 --- a/ev3classes/src/main/java/lejos/robotics/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Hardware abstraction interfaces for the robotics package. - */ -package lejos.robotics; diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/AstarSearchAlgorithm.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/AstarSearchAlgorithm.java deleted file mode 100644 index 5dcdafe..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/AstarSearchAlgorithm.java +++ /dev/null @@ -1,135 +0,0 @@ -package lejos.robotics.pathfinding; - -import java.util.*; -import lejos.robotics.navigation.Waypoint; - -// TODO: This works, but this code keeps the Node properties right in the Node object. The same Node set -// (aka Navigation Mesh) might conceivably (probably) be used repeatedly for many different searches. So things -// like setPredecessor() and setG_Score() should be temporary, not part of Node object? - -/** - * This is an implementation of the A* search algorithm. Typically this object would be instantiated and then used - * in a NodePathFinder constructor, along with a set of connected nodes. - * @see lejos.robotics.pathfinding.NodePathFinder - * @author BB - * - */ -public class AstarSearchAlgorithm implements SearchAlgorithm{ - /* - * DEVELOPER NOTES: This algorithm was adapted from pseudocode in the Wikipedia article: - * http://en.wikipedia.org/wiki/A*_search_algorithm - */ - - private static final String STRING_NAME = "A*"; - - int main_loop = 0; // TODO: DELETE ME - int neighbor_loop = 0; - - public Path findPath(Node start, Node goal) { - - //long startNanoT = System.nanoTime(); - - ArrayList closedset = new ArrayList(); // The set of nodes already evaluated. Empty at start. - ArrayList openset = new ArrayList(); // The set of tentative nodes to be evaluated. - openset.add(start); // openset contains startNode at start. - //ArrayList path = new ArrayList(); // came_from := the empty map // The map of navigated nodes. - start.setG_Score(0); // Distance from start along optimal path. Zero by definition since at start. g(start) - //start.setH_Score((float)Point2D.distance(start.x, start.y, goal.x, goal.y)); // ORIGINAL h(start) - start.setH_Score(start.calculateH(goal)); // NEW2 - - while (!openset.isEmpty()) { - Node x = getLowestCost(openset); // get the node in openset having the lowest f_score[] value - - main_loop++; // TODO: DELETE ME - - if(x == goal) { - Path final_path = new Path(); - - //long totalNanoT = System.nanoTime() - startNanoT; - //long reconNanoT = System.nanoTime(); - reconstructPath(goal, start, final_path); - //long totalReconT = System.nanoTime() - reconNanoT; - //System.out.println("Path time " + (totalNanoT/1000000D) + " ms"); - //System.out.println("Recon time " + (totalReconT/1000000D) + " ms"); - //System.out.println("MAIN LOOPS: " + main_loop); - //System.out.println("NEIGHB LOOPS: " + neighbor_loop); - //Button.ESCAPE.waitForPressAndRelease(); - return final_path; - } - openset.remove(x); // remove x from openset - closedset.add(x); // add x to closedset - - // TODO: Any mem saving/speedup not using iter? Could use array. Saves about 33 ms total, not really worth it yet? - Collection yColl = x.getNeighbors(); - Iterator yIter = yColl.iterator(); - - while(yIter.hasNext()) { // for each y in neighbor_nodes(x) - neighbor_loop++; // TODO: DELETE ME - Node y = yIter.next(); - if(closedset.contains(y)) continue; // if y in closedset already, go to next one - - //float tentative_g_score = x.getG_Score() + (float)Point2D.distance(x.x, x.y, y.x, y.y); // ORIGINAL g_score[x] + dist_between(x,y) - float tentative_g_score = x.getG_Score() + x.calculateG(y); // NEW2 - boolean tentative_is_better = false; - - if (!openset.contains(y)) { // if y not in openset - openset.add(y); // add y to openset - tentative_is_better = true; - } else if(tentative_g_score < y.getG_Score()) { // if tentative_g_score < g_score[y] - tentative_is_better = true; - } else - tentative_is_better = false; - - if (tentative_is_better) { - y.setPredecessor(x); // came_from[y] := x - } - - y.setG_Score(tentative_g_score); - y.setH_Score(y.calculateH(goal)); // NEW2 - //y.setH_Score((float)Point2D.distance(y.x, y.y, goal.x, goal.y)); // ORIGINAL heuristic_estimate_of_distance(y, goal) - // Update(closedset,y) This might mean update the values of y in closedset and openset? Unneeded I assume. - // Update(openset,y) - } // while yIter.hasNext() - } // while main loop - return null; // returns null if fails to find a continuous path. - } - - /** - * Finds the node within a set of neighbors with the least cost (potentially shortest distance to goal). - * @return The node with the least cost. - */ - private static Node getLowestCost(Collection nodeSet) { - /* TODO: This method has potential for optimization. Called very frequently. Probably best to - * move this method to Node (not NavigationMesh), then can optimize individually based on mesh - * type (e.g. integer grid or float navigation mesh). Mesh would probably be preferable, but - * SearchAlgorithm has no access to the mesh, just individual nodes. Perhaps alternate findPath() - * or set method for accepting mesh? (float or int is optimization concern) */ - Iterator nodeIterator = nodeSet.iterator(); - Node best = nodeIterator.next(); - while(nodeIterator.hasNext()) { - Node cur = nodeIterator.next(); - if(cur.getF_Score() < best.getF_Score()) - best = cur; - } - return best; - } - - /** - * Given the current node and the start node, this method retraces the completed path. It relies - * on Node.getPredecessor() to backtrack using recursion. - * - * @param current_node - * @param start - * @param path The path output by this algorithm. - */ - private static final void reconstructPath(Node current_node, Node start, Collection path){ - if(current_node != start) - reconstructPath(current_node.getPredecessor(), start, path); - path.add(new Waypoint(current_node.x, current_node.y)); - return; - } - - public String toString() { - return STRING_NAME; - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/DijkstraPathFinder.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/DijkstraPathFinder.java deleted file mode 100644 index d476580..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/DijkstraPathFinder.java +++ /dev/null @@ -1,446 +0,0 @@ -package lejos.robotics.pathfinding; - -import lejos.robotics.geometry.*; -import lejos.robotics.mapping.LineMap; -import lejos.robotics.navigation.DestinationUnreachableException; -import lejos.robotics.navigation.Pose; -import lejos.robotics.navigation.Waypoint; -import lejos.robotics.navigation.WaypointListener; - -import java.util.*; - -/** - * This class calculates the shortest path from a starting point to a finish point. - * while avoiding obstacles that are represented as a set of straight lines. - * The path passes through the end points of some of these lines, which is where the - * changes of direction occur. Since the robot is not point, the lines representing - * the obstacles should be lengthened so the actual robot will miss the actual obstacles. - * Use the lengthenLines() method to do this. - * Uses the A* algorithm, a variant of the Dijkstra shortest path algorithm - * It uses the Node inner class for its internal representation of points. - * - * @author Roger Glassey - */ -public class DijkstraPathFinder implements PathFinder -{ - - - -public DijkstraPathFinder(LineMap map) -{ - setMap(map); -} -/** - * Finds the shortest path from start to finish using the map (or collection of lines) - * in the constructor. - * @param start the initial robot pose - * @param finish the final robot location - * @return the shortest route - * @throws DestinationUnreachableException if, for example, you nave not called setMap(); - */ - public Path findRoute(Pose start, Waypoint finish) throws DestinationUnreachableException - { - return findPath(start.getLocation(), finish, _map); - } - - /** - * Finds the shortest path from start to finish using the map (or collection of lines) - * in the constructor. - * @param start the initial robot pose - * @param finish the final robot location - * @param theMap the LineMap of obstacles - * @return the shortest route - * @throws DestinationUnreachableException if, for example, you nave not called setMap(); - */ - public Path findRoute(Pose start, Waypoint finish, LineMap theMap) throws DestinationUnreachableException - { - setMap(theMap); - return findPath(start.getLocation(), finish, _map); - } - /** - * finds the shortest path between start and finish Points whild avoiding the obstacles - * in the map - * @param start : the beginning of the path - * @param finish : the destination - * @param theMap that contains the obstacles - * @return an array list of waypoints. If no path exists, returns null - */ - - private Path findPath(Point start, Point finish, ArrayList theMap)throws DestinationUnreachableException - { - _map = theMap; - initialize(); // in case this method has already been called before - Node source = new Node(start); - Node destination = new Node(finish); // current destination - source.setSourceDistance(0); - _reached.add(source); - _candidate.add(destination); - Node from; // current start node - Node dest; // current destination node - int index = _candidate.size()-1; //index of current destination in candidate set - boolean failed = false; - - while (_candidate.size() > 0 && !failed) - { - _count++; - // get destination from inCandidateSet set - dest = _candidate.get(index); - from = getBest(dest); - float distance = from.getDistance(dest); - if (distance >= BIG) // dest is known to be blocked from best node in _reached - { - index--; // try another temporary start node - failed = index < 0; // tried the whole stack. - } else - { // dest is not known to be blocked from best reached node - if (segmentBlocked(from, dest)) - { // this method call possibly created and added new nodes to the _candidate set - from.block(dest);// Record dest as not directly reachable - index = _candidate.size() - 1; // search from top from top of stack - } else // not blocked so dest node has is reached - { - if (distance < .05f) // essentially same node as best node in _reached, - { // so will not be a separate way point in the route - dest.setPredecessor(from.getPredecessor()); - dest.setSourceDistance(from.getSourceDistance()); - } else - { - dest.setPredecessor(from); // allows backtracking to recover the path - dest.setSourceDistance(from.getSourceDistance() + from.getDistance(dest)); - } - // move dest from _candidate to _reached - _reached.add(dest); - _candidate.remove(dest); // pop the stack - index = _candidate.size() - 1; - } // end else dest not blocked - - } // end else dest not previously blocked - }// end while - if (failed) - { - throw new DestinationUnreachableException(); -// return null; - } - return getRoute(destination); - } - - public void setMap(ArrayList theMap) - { - _map = theMap; - } - - public void setMap(LineMap theMap) - { - Line [] lines = theMap.getLines(); - for(int i = 0; i < lines.length; i++) - _map.add(lines[i]); - } - - - /** - * lengthens all the lines in the map by delta at each end - * @param delta added to each end of each line - */ - public void lengthenLines( float delta) - { - for (Line line : _map) - { - line.lengthen(delta); - } - } - protected void initialize() - { - _reached = new ArrayList(); - _candidate = new ArrayList(); - } - - /** - * helper method for findPath(). Determines if the straight line segment - * crosses a line on the map. - * Side effect: creates nodes at the end of the blocking line and adds them to the _candidate set - * @param from the beginning of the line segment - * @param theDest the end of the line segment - * @return true if the segment is blocked - */ - protected boolean segmentBlocked(final Node from, final Node theDest) - { - Node to = new Node(theDest.getLocation()); // alias the destination - Node n1 = null; // one end of the blocking line - Node n2 = null; // other end of the blocking line - Line line = null; // the line connecting from node with to node - Point intersection; // point where the segment crosses the blocking line - boolean blocked = false; - Line segment = new Line(from.getX(), from.getY(), - to.getX(), to.getY()); - for (Line l : _map)// test ever line in the map to see if it blocks the segment - { - intersection = l.intersectsAt(segment); - if (intersection != null && !from.atEndOfLine(l) && !to.atEndOfLine(l)) - { //segment is legal if it starts or ends at an end point of the line - line = l; - blocked = true; - }// nodes at end of the line - } - if (blocked) // add end points of the blocking segment to inCandidateSet set - { - Point p1 = line.getP1(); - Point p2 = line.getP2(); - n1 = new Node((float)p1.getX(),(float)p1.getY()); - if(!inReachedSet(n1) &&!inCandidateSet(n1)) - { - n1.setSourceDistance(from.getSourceDistance() + from.getDistance(n1)); - _candidate.add(n1); - } - n2 = new Node((float)p2.getX(),(float)p2.getY()); - if(!inReachedSet(n2) && !inCandidateSet(n2)) - { - n2.setSourceDistance(from.getSourceDistance() + from.getDistance(n2)); - _candidate.add(n2); - } - } - return blocked; - } - - /** - * Helper method for findPath()
    - * returns the node in the Reached set, whose distance from the start node plus - * its straight line distance to the destination is the minimum. - * @param currentDestination : the current destination node, (in the Candidate set) - * @return the node the node which could be the last node in the shortest path - */ - protected Node getBest(Node currentDestination) - { - Node best = _reached.get(0); - float minDist = best._sourceDistance + best.getDistance(currentDestination); - for (Node n : _reached) - { - float d = n._sourceDistance + n.getDistance(currentDestination); - if (d < minDist) - { - minDist = d; - best = n; - } - } - return best; - } - - - /** - * helper method for findPath; check if aNode is in the set of reached nodes - * @param aNode - * @return true if aNode has been reached already - */ - protected boolean inReachedSet(final Node aNode) - { - boolean found = false; - for (Node n : _reached) - { - found = aNode.getLocation().equals(n.getLocation()); - if (found) break; - } - return found; - } - -/** - * helper method for findPath; check if aNode is in the set of candidate nodes - * @param aNode - * @return true if aNode has been reached already - */ - protected boolean inCandidateSet(final Node aNode) - { - boolean found = false; - for (Node n : _candidate) - { - found = aNode.getLocation().equals(n.getLocation()); - if (found) break; - } - return found; - } - - /** - * helper method for find path()
    - * calculates the route backtracking through predecessor chain - * @param destination - * @return the route of the shortest path - */ -protected Path getRoute(Node destination) -{ - Path route = new Path(); - Node n = destination; - Waypoint w ; - do { // add waypoints to route as push down stack - w = new Waypoint(n.getLocation()); - route.add(0, w); - n = n.getPredecessor(); - } while (n != null); - return route; -} - protected ArrayList getMap() - { - return _map; - } - public int getIterationCount(){ return _count;} - - public int getNodeCount(){return _reached.size();} - - public void addListener(WaypointListener wpl) { - if(listeners == null )listeners = new ArrayList(); - listeners.add(wpl); - } - - public void startPathFinding(Pose start, Waypoint end) { - Collection solution = null; - try { - solution = findPath(start.getLocation(), end, _map); - } catch (DestinationUnreachableException e) { - // TODO Not sure how to handle this. - e.printStackTrace(); - } - if(listeners != null) { - for(WaypointListener l : listeners) { - Iterator iterator = solution.iterator(); - while(iterator.hasNext()) { - l.addWaypoint(iterator.next()); - } - l.pathGenerated(); - } - } - } - - //*********** instance variables in ShortestPathFinder ******************* - private ArrayList listeners ; - - protected int _count = 0; - /** - * set by segmentBlocked() used by findPath() - */ - protected boolean _blocked = false; - - private static final float BIG = 999999999; - - /** - * the set of nodes that are candidates for being in the shortest path, but - * whose distance from the start node is not yet known - */ - protected ArrayList _candidate = new ArrayList(); - - /** - * the set of nodes that are candidates for being in the shortest path, and - * whose distance from the start node is known - */ - protected ArrayList _reached = new ArrayList(); - /** - * The map of the obstacles - */ - protected ArrayList _map = new ArrayList(); - - -//************Begin definition of Node class ********************** - protected class Node -{ - public Node(Point p) - { - _p = p; - } - public Node(float x, float y) - { - this(new Point(x,y)); - } - - -/** - * test if this Node is one of the ends of theLine - * @param theLine endpoints to check - * @return true if this node is an end of the line - */ - public boolean atEndOfLine(Line theLine) - { - return _p.equals(theLine.getP1()) || _p.equals(theLine.getP2()); - } - /** - * set the distance of this Node from the source - * @param theDistance - */ - public void setSourceDistance(float theDistance) - { - _sourceDistance = theDistance; - } - /** - * return the shortest path length to this node from the start node - * @return shortest distance - */ - public float getSourceDistance(){return _sourceDistance;} - - /** - * get the straight line distance from this node to aPoint - * @param aPoint - * @return the distance - */ - public float getDistance(Point aPoint) - { - - return (float)_p.distance(aPoint); - } - - /** - * return the straight distance from this node to aNode - * @param aNode - * @return the distance - */ - public float getDistance(Node aNode) - { - if(_blocked.indexOf(aNode) > -1) return BIG; - else return getDistance(aNode.getLocation()); - } - - /** - * return the location of this node - * @return the location - */ - public Point getLocation() - { - return _p; - } - - /** - * add aNode to list of nodes not a neighbour of this Node - * @param aNode - */ - public void block(Node aNode) - { - _blocked.add(aNode); - } - - /** - * set the predecessor of this node in the shortest path from the start node - * @param thePredecessor - */ - public void setPredecessor(Node thePredecessor) - {_predecessor = thePredecessor;} - /** - * get the predecessor of this node in the shortest path from the start - * @return the predecessor node - */ - public Node getPredecessor() { return _predecessor;} - - /** - * get the X coordinate of this node - * @return X coordinate - */ - public float getX(){return (float)_p.getX();} - /** - * get the Y coordinate of thes Node - * @return Y coordinate - */ - public float getY(){return (float)_p.getY();} - public String toString(){return " "+getX()+" , "+getY()+" ";} - protected Point _p; - protected float _sourceDistance; - protected Node _predecessor; - public ArrayList _blocked = new ArrayList(); - private float BIG = 100000; - } -// **************** end Node class **************************** - -} - diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/FourWayGridMesh.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/FourWayGridMesh.java deleted file mode 100644 index 8a45a18..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/FourWayGridMesh.java +++ /dev/null @@ -1,209 +0,0 @@ -package lejos.robotics.pathfinding; - -import java.util.ArrayList; -import java.util.Collection; - -import lejos.robotics.geometry.Line; -import lejos.robotics.geometry.Rectangle; -import lejos.robotics.mapping.LineMap; - -/** - * Generates a grid of nodes. Spacing between the grid nodes and clearance around map geometry can be specified. - * This set can be generated once at the beginning of a user program, and the same node set can be used for all - * subsequent navigation. - * @author BB - * - */ -public class FourWayGridMesh implements NavigationMesh { - - private ArrayList mesh = null; - private LineMap map = null; - private float clearance; - private float gridspace; - - /** - * Instantiates a grid mesh of nodes which won't interconnect between any map geometry. Will also keep away - * the set parameter from map geometry. Grid spacing is adjustable via the constructor. - * @param map The map containing geometry. - * @param gridSpace The size of each grid square. - * @param clearance The safety zone between all nodes/connections and the map geometry. - */ - public FourWayGridMesh(LineMap map, float gridSpace, float clearance) { - setMap(map); - setClearance(clearance); - setGridSpacing(gridSpace); - // TODO: OPTION 1: Generate now (predictable) or later (allows changes to be made to map? Nah.) - // Maybe generate called here? If called later, someone could add a node before it was - // generated and expect it to be connected, which it won't be. - } - - public Collection getMesh(){ - if(mesh == null) regenerate(); - return mesh; - } - - /** - * Change the size of each grid square. NOTE: When grid space value is changed, this class does not regenerate - * the navigation mesh until regenerate() is explicitly called. - * @param gridSpace The unit size of each grid square. - */ - public void setGridSpacing(float gridSpace) { - this.gridspace = gridSpace; - } - - /** - * Changes the safety zone between all nodes/connections and map geometry. This leaves a margin of error between - * potential object collisions and the robot. NOTE: When clearance value is changed, - * this class does not regenerate the navigation mesh until regenerate() is explicitly called. - * @param clearance The safety clearance between nodes/connections and map geometry. - */ - public void setClearance(float clearance) { - this.clearance = clearance; - } - - /** - * Feeds this class a new map. NOTE: When Map is changed, this class does not regenerate the navigation mesh - * until regenerate() is explicitly called. - * @param map The new map data. - */ - public void setMap(LineMap map) { - this.map = map; - } - - public void regenerate() { - //long startNanoT = System.nanoTime(); - //long startFreeMem = Runtime.getRuntime().freeMemory(); - - mesh = new ArrayList (); - - // First node is "clearance" from the corner of the map - Rectangle bounds = map.getBoundingRect(); - - float startx = bounds.x + clearance; - float starty = bounds.y + clearance; - - float endx = bounds.width + bounds.x - clearance; - float endy = bounds.height + bounds.y - clearance; - - int x_grid_squares = 0; - int y_grid_squares = 0; - - for(float y = starty;y= neighbors) { - mesh.add(node); - return total; - } - } - } - } - mesh.add(node); - return total; - } - - public boolean removeNode(Node node) { - //System.out.print("MAIN NODE "); - //outputNodeData(node); - Collection coll = node.getNeighbors(); - ArrayList arr = new ArrayList (coll); - for(int i=0;i getMesh(); - - // Note: Not used by NodePathFinder but seems useful for GUIs and such when parameters changed. - /** - * Throws away the previous set of nodes and recalculates them all. If any setting were changed, such as - * the spacing between nodes, then it will recalculate them with the new settings. - */ - public void regenerate(); - -} diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/Node.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/Node.java deleted file mode 100644 index 926e6fa..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/Node.java +++ /dev/null @@ -1,175 +0,0 @@ -package lejos.robotics.pathfinding; - - -import java.util.ArrayList; -import java.util.Collection; - -import lejos.robotics.geometry.Point2D; - -/** - * This class represents a Node which can be connected to other neighboring nodes. Node sets can be searched using - * search algorithms. Typically the search algorithm only requires one starting node and one goal node. It assumes these - * nodes are linked by intermediate nodes. - * @author BB - * @see lejos.robotics.pathfinding.SearchAlgorithm - */ -public class Node { - - /** - * This constant is multiplied with the float coordinate to get an integer for faster internal - * computations. A multiplier of 100 gives the equivalent of 2 decimal places (1.2345 = 123) - */ - static final int MULTIPLIER = 100; - - /** - * The x coordinate of this node. - */ - public float x; - - /** - * The y coordinate of this node. - */ - public float y; - - /** - * The cumulative distance from the start node to this node. - */ - private float g_score = 0; - - /* - * The estimated distance to the goal node from this node. Distance "as the crow flies" - */ - private float h_score = 0; - - /** - * The predecessor node used by A* search algorithm to mark off the previous node in the search tree. - */ - private Node cameFrom = null; - - /** - * List of neighbors to this node. - */ - private ArrayList neighbors = new ArrayList(); - - /** - * Creates a new instance of a node. - * @param x The x coordinate of this node. - * @param y The y coordinate of this node. - */ - public Node(float x, float y) { - this.x = x; - this.y = y; - } - - /** - * Returns all the neighbors which this node is connected to. - * @return The collection of all neighboring nodes. - */ - public Collection getNeighbors() { - return neighbors; - } - - /** - * Indicates the number of neighbors (nodes connected to this node). - * @return int Number of neighbors. - */ - public int neighbors() { - return neighbors.size(); - } - - /** - * Adds a neighboring node to this node, connecting them together. Note: You must make sure to add this node - * to the neighbor, and also add the neighbor to this node. This method doesn't do both. - * @param neighbor The neighboring node to connect with. - * @return Returns false if the neighbor already existed, or if you try to add this node to itself as a neighbor. - */ - public boolean addNeighbor(Node neighbor) { - // TODO: OPTION - Maybe code here should add each other as neighbors? - // Check to make sure same isn't added twice. (Assuming ArrayList doesn't do this already?) - if(neighbors.contains(neighbor)) return false; - // Check to make sure doesn't add itself - if(neighbor == this) return false; - neighbors.add(neighbor); - return true; - } - - /** - * Removes a node from this node as neighbors, effectively disconnecting them. Note: You have to remove - * this node from the neighbor, and also remove the neighbor from this node. This method doesn't do both. - * @param neighbor The neighboring node to disconnect from. - * @return Returns false if the neighbor did not previously exist as a neighbor. - */ - public boolean removeNeighbor(Node neighbor) { - // TODO: Maybe code here should remove each other as neighbors? - return neighbors.remove(neighbor); - } - - /** - * Method used by A* to calculate search score. The H score is the estimated distance to the goal node from this node. - * It can either be distance "as the crow flies" or in the case of a grid navigation mesh, the minimum number - * of grid spaces to get to the goal node (x squares horizontally + y squares vertically from goal). - * NOTE: There is no getH_score() because the A* algorithm only needs to set this value, not retrieve it. - * @param h - */ - protected void setH_Score(float h) { - h_score = h; - } - - /** - * Calculates the distance to a neighbor node. This method is used to optimize the algorithm. - * @param neighbor - * @return the distance to neighbor - */ - protected float calculateG(Node neighbor) { - return (float)Point2D.distance(this.x, this.y, neighbor.x, neighbor.y); - } - - /** - * Calculates the distance to the goal node. This method is used to optimize the algorithm. - * @param goal - * @return the distance to goal - */ - protected float calculateH(Node goal) { - return calculateG(goal); - } - - /** - * Method used by A* to calculate search score. The G score is the cumulative distance from the start node to this node. - * @param g - */ - protected void setG_Score(float g) { - g_score = g; - } - - /** - * Method used by A* to calculate search score. The G score is the cumulative distance from the start node to this node. - * @return the search score - */ - protected float getG_Score(){ - return g_score; - } - - /** - * Method used by A* to calculate search score. You can't set FScore because it is - * derived internally by adding the gscore and hscore. - */ - protected float getF_Score(){ - return g_score + h_score; - } - - /** - * Used by A* search. Stores the node that the search came from prior to this node. - * @return the predecessor node - */ - protected Node getPredecessor() { - return cameFrom; - } - - /** - * Used by A* search. Stores the node that the search came from prior to this node. - * @param orig - */ - protected void setPredecessor(Node orig) { - cameFrom = orig; - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/NodePathFinder.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/NodePathFinder.java deleted file mode 100644 index a3a0f8b..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/NodePathFinder.java +++ /dev/null @@ -1,107 +0,0 @@ -package lejos.robotics.pathfinding; - -import java.util.ArrayList; -import java.util.Iterator; - -import lejos.robotics.navigation.*; - -/** - * This path finder class uses one of the common search algorithms (e.g. A*) and a navigation mesh (e.g. grid) and - * uses them to find a path around map geometry. - * - * @author BB - * - */ -public class NodePathFinder implements PathFinder{ - - private ArrayList listeners; - private SearchAlgorithm alg; - private NavigationMesh mesh = null; - - /** - * Instantiates a NodePathFinder object using a specified algorithm. Ideally this class would work with - * self propagating nodes, but it currently is not able to. - * @param alg - */ - private NodePathFinder(SearchAlgorithm alg) { - // TODO: This method is not really valid (hence why market private for now) because the - // algorithm will currently not work without a mesh. - setSearchAlgorithm(alg); - } - - /** - * Instantiates a NodePathFinder object using a specified algorithm. The supplied mesh is used - * to add and remove nodes (start and goal) when requesting a path. - * @param alg The search algorithm. - * @param mesh The navigation mesh is a set of nodes in various configurations (e.g. grid). - */ - public NodePathFinder(SearchAlgorithm alg, NavigationMesh mesh) { - this(alg); - setNavMesh(mesh); - } - - /** - * Method for changing the navigation mesh after this has been instantiated. - * @param mesh - */ - public void setNavMesh(NavigationMesh mesh) { - this.mesh = mesh; - } - - /** - * Method for changing the search algorithm after this has been instantiated. - * @param alg - */ - public void setSearchAlgorithm(SearchAlgorithm alg) { - this.alg = alg; - } - - public void addListener(WaypointListener wpl) { - if(listeners == null )listeners = new ArrayList(); - listeners.add(wpl); - } - - public Path findRoute(Pose start, Waypoint goal) - throws DestinationUnreachableException { - // Step 1: Make nodes out of start and destination - // TODO: Big problem: These nodes will not be linked to anything if no mesh was given! - Node startNode = new Node(start.getX(), start.getY()); - Node goalNode = new Node((float)goal.getX(), (float)goal.getY()); - - // Step 2: If Mesh is not null, add them to set? - if(mesh != null) { - mesh.addNode(startNode, 4); - mesh.addNode(goalNode, 4); - } - // Step 3: Use alg to find path. - Path path = alg.findPath(startNode, goalNode); - if(path == null) throw new DestinationUnreachableException(); - - // Step 4: If mesh is not null, remove them from set? - if(mesh != null) { - mesh.removeNode(startNode); - mesh.removeNode(goalNode); - } - - return path; - } - - public void startPathFinding(Pose start, Waypoint end) { - Path solution = null; - try { - solution = findRoute(start, end); - } catch (DestinationUnreachableException e) { - // TODO: Call pathComplete() on all listeners with false if unable to find route. - // l.pathComplete(false); // Code should be below. Mark boolean success as false here. - } - if(listeners != null) { - for(WaypointListener l : listeners) { - Iterator iterator = solution.iterator(); // TODO: If solution null, this can crash here. - while(iterator.hasNext()) { - l.addWaypoint(iterator.next()); - } - l.pathGenerated(); - } - } - } -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/Path.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/Path.java deleted file mode 100644 index b04c01d..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/Path.java +++ /dev/null @@ -1,34 +0,0 @@ -package lejos.robotics.pathfinding; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import lejos.robotics.Transmittable; -import lejos.robotics.navigation.Waypoint; - -/** - * Represents a path consisting of an ordered collection of waypoints - * - * @author Lawrie Griffiths - * - */ -public class Path extends ArrayList implements Transmittable { - - public void dumpObject(DataOutputStream dos) throws IOException { - dos.writeInt(this.size()); - for(Waypoint wp: this) { - wp.dumpObject(dos); - } - } - - public void loadObject(DataInputStream dis) throws IOException { - int n = dis.readInt(); - this.clear(); - for(int i=0;i listeners ; - - public RandomPathFinder(RangeMap map, RangeReadings readings) { - this.map = map; - this.readings = readings; - } - - /** - * Set the maximum valid range readings - * @param range the maximum range - */ - public void setMaxRange(float range) { - maxRange = range; - } - - /** - * Set the maximum distance between waypoints - * @param distance the maximum distance - */ - public void setMaxDistance(float distance) { - maxDistance = distance; - } - - /** - * Set the maximum number of iterations before giving up when searching for a path - * @param iterations the maximum number of iterations - */ - public void setMaxIterations(int iterations) { - maxIterations = iterations; - } - - /** - * Set the clearance around the edge of the map. - * This does not really work as clearance shiould be around all - * walls and obstacles. - * - * @param clearance the clearance - */ - public void setClearance(float clearance) { - this.clearance = clearance; - } - - public Path findRoute(Pose start, Waypoint destination) - throws DestinationUnreachableException { - Pose pose = start; - Path route = new Path(); - - // Continue until we return a route or throw DestinationUnReachableException - for(;;) { - // If the current pose if close enough to the destination, - // and there are no obstacles in the way, go straight there - Pose testPose = pose; - testPose.setHeading(testPose.angleTo(destination)); - if (testPose.distanceTo(destination) < maxDistance && - map.range(testPose) >= testPose.distanceTo(destination)) { - route.add(new Waypoint(destination)); - return route; - } - testPose = null; - - // Generate random poses and apply tests to them - int i; - for(i=0;i maxDistance) continue; - - // The new pose must be at least MIN_GAIN closer to the destination - if (pose.distanceTo(destination) - - testPose.distanceTo(destination) < minGain) - continue; - - // We must be able to get a valid set of range readings from the new pose - float heading = testPose.getHeading(); - boolean validReadings = true; - for(RangeReading r: readings) { - testPose.setHeading(heading + r.getAngle()); - float range = map.range(testPose); - if (range > maxRange) { - validReadings = false; - break; - } - } - if (!validReadings) continue; - - //Check there are no obstacles in the way - testPose.setHeading(testPose.angleTo(pose.getLocation())); - if (map.range(testPose) < testPose.distanceTo(pose.getLocation())) - continue; - //System.out.println("Range = " + map.range(testPose)); - //System.out.println("DistanceTo = " + testPose.distanceTo(pose.getLocation())); - //System.out.println("From = " + pose); - //System.out.println("To = " + testPose); - - testPose.setHeading(heading); // Restore heading - break; // We have a new way point - } - if (i == maxIterations) throw new DestinationUnreachableException(); - route.add(new Waypoint(testPose)); - pose = testPose; - } - } - - /** - * Generate a random pose within the mapped area, not too close to the edge - */ - private Pose generatePose() { - float x, y, heading; - Rectangle boundingRect = map.getBoundingRect(); - Rectangle innerRect = new Rectangle(boundingRect.x + clearance, boundingRect.y + clearance, - boundingRect.width - clearance * 2, boundingRect.height - clearance * 2); - - // Generate x, y values in bounding rectangle - for (;;) { // infinite loop that we break out of when we have - // generated a particle within the mapped area - x = innerRect.x + (((float) Math.random()) * innerRect.width); - y = innerRect.y + (((float) Math.random()) * innerRect.height); - - if (map.inside(new Point(x, y))) break; - } - - // Pick a random angle - heading = ((float) Math.random()) * 360; - - return new Pose(x,y,heading); - } - - public void addListener(WaypointListener wpl) { - if(listeners == null )listeners = new ArrayList(); - listeners.add(wpl); - } - - public void startPathFinding(Pose start, Waypoint end) { - Collection solution = null; - try { - solution = findRoute(start, end); - } catch (DestinationUnreachableException e) { - // TODO Not sure what the proper response is here. All in one. - return; - } - if(listeners != null) { - for(WaypointListener l : listeners) { - Iterator iterator = solution.iterator(); - while(iterator.hasNext()) { - l.addWaypoint(iterator.next()); - } - l.pathGenerated(); - } - } - } -} diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/RandomSelfGeneratingNode.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/RandomSelfGeneratingNode.java deleted file mode 100644 index 9973fa4..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/RandomSelfGeneratingNode.java +++ /dev/null @@ -1,112 +0,0 @@ -package lejos.robotics.pathfinding; - - -import java.util.Collection; - -import lejos.robotics.geometry.Point2D; - -/** - * This Node is able to randomly generate its own neighbors via the getNeighbors() method. The number of neighbors - * and possible distances to the neighbors are determined in the constructor. The first instance of this node is generally - * the start node used in algorithms. The goal node is just a regular node that is automatically linked to this set - * when the dynamically created nodes come within range of the goal node. - * Note: Because the nodes are randomly generated, there is no guarantee they will come within range of the goal node - * and successfully link up. However, in practice they will always connect if you use enough connections (minimum 3-4) and - * a long enough maxDist. - * @author BB - * - */ -public class RandomSelfGeneratingNode extends Node { - - // TODO: Add ability to prune out paths that come close to map data objects. - - /** - * firstCall indicates if getNeighbors() has been called yet. false = has been called - */ - private boolean firstCall = true; - - private int connections; - private float maxDist; - - // TODO: Making the goal node static blows apart the possibility of using two sets of random nodes with different goals. - private static Node goal = null; - - /** - * Creates a node that will randomly generate 'connections' number of neighbors when getNeighbors() - * is called. These neighbors will be within range of 'maxDist'. - * @param x The x coordinate of this node. - * @param y The y coordinate of this node. - * @param maxDist The maximum x or y distance to create new nodes randomly. - * @param connections The number of neighbors to randomly generate and connect with. - */ - public RandomSelfGeneratingNode(float x, float y, float maxDist, int connections) { - super(x, y); - this.maxDist = maxDist; - this.connections = connections; - } - - /** - * Creates a node that will randomly generate 'connections' number of neighbors when getNeighbors() - * is called. These neighbors will be within range of 'maxDist'. - * @param x The x coordinate of this node. - * @param y The y coordinate of this node. - * @param maxDist The maximum x or y distance to create new nodes randomly. - * @param connections The number of neighbors to randomly generate and connect with. - * @param goal The goal node which is added to this set and connected to any nodes within range. - */ - public RandomSelfGeneratingNode(float x, float y, float maxDist, int connections, Node goal) { - this(x, y, maxDist, connections); - RandomSelfGeneratingNode.goal = goal; - } - - /** When this method is called the first time, it randomly generates a set of neighbors according to - * the parameters in the constructor. It then calls addNeighbor() for each one. The next time getNeighbors() is called - * it will return the same set of neighbors it initially generated. - * - * Each of these neighbors is a RandomSelfGeneratingNode too, so when their neighbors are requested they will also - * self-generate a set of neighbors. - * - * Each random node will also add the "parent" node to its list of neighboring nodes. - * - * If a goal node was added, it checks if the node is within maxDist of the goal node. If it is, both the goal node and - * this node add each other as neighbors. - * @return a collection of RandomSelfGeneratingNode objects. - */ - public Collection getNeighbors() { - // TODO: When to do the map geometry pruning of these? - if(firstCall) { - - // TODO: Really, if any of the previously generated nodes are in range, they should be connected. Means it would - // need to scrutinize every previous node generated. Either backtrack using Node.getPredecessor() or keep another - // list of all nodes generated so far. - // See if goal node is in range. Yes? Add. - float goal_dist = (float)Point2D.distance(goal.x, goal.y, this.x, this.y); - if(goal_dist <= maxDist) { - this.addNeighbor(goal); - goal.addNeighbor(this); - } - - int nodes_to_add = connections - super.neighbors(); - for(int i=0;i theMap) - throws DestinationUnreachableException - { - _map = theMap; - initialize(); // in case this method has already been called before - Node source = new Node(start); - _destination = new Node(finish); // current destination - - if (_debug) - System.out.println("Start " + source + " Destination " - + _destination); - source.setSourceDistance(0); - _reached.add(source); - _candidate.add(_destination); - boolean failed = false; - Node bestCandidate = null; - Node bestReached = null; - // The real work is here: - while (!_reached.contains(_destination) && !failed) - { - _count++; - float minDistance = BIG; - float distance;// find node closest to source; check all combinations of reached and candidate nodes - for (Node reached : _reached) - { - for (Node candidate : _candidate) - { - if (!reached.isBlocked(candidate))// candidate node not already blocked from reached node - { - distance = reached._sourceDistance - + reached.getDistance(candidate); - if (minDistance > distance) - { - minDistance = distance; - bestReached = reached; - bestCandidate = candidate; - } - } - } - } - if (_debug) - System.out.println("bestCandidate " + bestCandidate - + " minDist " + minDistance); - // is the line from bestReached to bestCandidate blocked? The segmentBlocked method adds nodes - if (!segmentBlocked(bestReached, bestCandidate)) - { - { - bestCandidate.setPredecessor(bestReached); // allows backtrack to recover the path - bestCandidate.setSourceDistance(minDistance); - } - // move bestCandidate from _candidate set to _reached set - _reached.add(bestCandidate); - _candidate.remove(bestCandidate); - if (_debug) - System.out.println("Moved from candidate to reached " - + bestCandidate + " source dist " - + bestCandidate.getSourceDistance() + " of " - + _candidate.size()); - } else - { // line from bestReached to bestCandidate is blocked - if (_debug) - System.out.println("bestCandidate " + bestCandidate - + " blocked from " + bestReached); - bestReached.block(bestCandidate); - bestCandidate.block(bestReached); - } - failed = minDistance >=BIG; - }// end while - if (failed) - throw new DestinationUnreachableException(); - if (_debug) - { - System.out.println("DONE iteration count = " + _count); - for (Node n : _reached)System.out.println("Node "+n+"Distance from source" + n.getSourceDistance()); - } - return getRoute(_destination); - } - - /** - * Helper method for findPath(). Determines if the straight line segment - * crosses a line on the map. Side effect: creates nodes at the end of the - * blocking line and adds them to the _candidate set - * - * @param from - * the beginning of the line segment - * @param theDest - * the end of the line segment - * @return true if the segment is blocked - */ - private boolean segmentBlocked(final Node from, final Node theDest) - { - Node to = new Node(theDest.getLocation()); // alias the destination - Node n1 = null; // one end of the blocking line - Node n2 = null; // other end of the blocking line - Line line = null; // the line connecting from node with to node - Point intersection; // point where the segment crosses the blocking line - boolean blocked = false; - Line segment = new Line(from.getX(), from.getY(), to.getX(), to.getY()); - for (Line l : _map)// test every line in the map to see if it blocks the segment - { - intersection = l.intersectsAt(segment); - if (intersection != null && !from.atEndOfLine(l) - && !to.atEndOfLine(l)) - { // segment is not blocked if the intersection point is not a line end. - line = l; - blocked = true; - break; - }// nodes at end of the line - } - if (blocked) // add end points of the blocking segment to inCandidateSet - // set - { - if (_debug) - System.out.println(" blocked from " + from + " to " + theDest); - Point p1 = line.getP1(); - Point p2 = line.getP2(); - n1 = new Node((float) p1.getX(), (float) p1.getY()); - if (!inReachedSet(n1) && !inCandidateSet(n1)) - { - n1.setSourceDistance(from.getSourceDistance() - + from.getDistance(n1)); - _candidate.add(n1); - if (_debug) - System.out.println("Candidate add n1 " + n1 - + " Source Distance " + n1.getSourceDistance()); - } - n2 = new Node((float) p2.getX(), (float) p2.getY()); - if (!inReachedSet(n2) && !inCandidateSet(n2)) - { - n2.setSourceDistance(from.getSourceDistance() - + from.getDistance(n2)); - _candidate.add(n2); - if (_debug) - System.out.println("Candidate add n2 " + n2 - + " Source Distance " + n2.getSourceDistance()); - } - } - return blocked; - } - - /** - * helper method for findPath; check if aNode is in the set of reached nodes - * - * @param aNode - * @return true if aNode has been reached already - */ - private boolean inReachedSet(final Node aNode) - { - boolean found = false; - for (Node n : _reached) - { - found = aNode.equals(n); - if (found) - break; - } - return found; - } - - /** - * helper method for findPath; check if aNode is in the set of candidate - * nodes - * - * @param aNode - * @return true if aNode has been reached already - */ - public boolean inCandidateSet(final Node aNode) - { - boolean found = false; - for (Node n : _candidate) - { - found = aNode.equals(n); - if (found) - break; - } - return found; - } - - /** - * helper method for find path()
    - * calculates the route backtracking through predecessor chain - * - * @param destination - * @return the route of the shortest path - */ - private Path getRoute(Node destination) - { - Path route = new Path(); - Node n = destination; - Waypoint w; - do - { // add waypoints to route as push down stack - w = new Waypoint(n.getLocation()); - route.add(0, w); - n = n.getPredecessor(); - } while (n != null); - return route; - } - - public void setMap(ArrayList theMap) - { - _map = theMap; - } - - public void setMap(LineMap theMap) - { - Line[] lines = theMap.getLines(); - for (int i = 0; i < lines.length; i++) - _map.add(lines[i]); - } - - public void setDebug(boolean yes) - { - _debug = yes; - } - - /** - * lengthens all the lines in the map by delta at each end - * - * @param delta - * added to each end of each line - */ - public void lengthenLines(float delta) - { - for (Line line : _map) - { - line.lengthen(delta); - } - } - - private void initialize() - { - _reached = new ArrayList(); - _candidate = new ArrayList(); - } - - public ArrayList getMap() - { - return _map; - } - - public int getIterationCount() - { - return _count; - } - - public int getNodeCount() - { - return _reached.size(); - } - - public void addListener(WaypointListener wpl) - { - if (listeners == null) - listeners = new ArrayList(); - listeners.add(wpl); - } - - public void startPathFinding(Pose start, Waypoint end) - { - Path solution = null; - try - { - solution = findPath(start.getLocation(), end, _map); - } catch (DestinationUnreachableException e) - { - System.out.println("Destinatin "+_destination +" not reachable "); - return; - } - if (listeners != null) - { - for (WaypointListener l : listeners) - { - Iterator iterator = solution.iterator(); - while (iterator.hasNext()) - { - l.addWaypoint(iterator.next()); - } - l.pathGenerated(); - } - } - } - // *********** instance variables in ShortestPathFinder ******************* - private ArrayList listeners; - private int _count = 0; - private static final float BIG = 999999999; - private Node _destination; - private Node _source; - /** - * the set of nodes that are candidates for being in the shortest path, but - * whose distance from the start node is not yet known. - */ - private ArrayList _candidate = new ArrayList(); - /** - * the set of nodes that are candidates for being in the shortest path, and - * whose distance from the start node is known - */ - private ArrayList _reached = new ArrayList(); - /** - * The map of the obstacles - */ - private ArrayList _map = new ArrayList(); - private boolean _debug = false; - - // ************Begin definition of Node class ********************** - public class Node - { - public Node(Point p) - { - _p = p; - } - - private Node(float x, float y) - { - this(new Point(x, y)); - } - - /** - * test if this Node is one of the ends of theLine - * - * @param theLine - * endpoints to check - * @return true if this node is an end of the line - */ - private boolean atEndOfLine(Line theLine) - { - return _p.equals(theLine.getP1()) || _p.equals(theLine.getP2()); - } - - /** - * Set the distance of this Node from the source - * - * @param theDistance - */ - private void setSourceDistance(float theDistance) - { - _sourceDistance = theDistance; - } - - /** - * Return the shortest path length to this node from the start node - * - * @return shortest distance - */ - private float getSourceDistance() - { - return _sourceDistance; - } - - /** - * Get the straight line distance from this node to aPoint - * - * @param aPoint - * @return the distance - */ - private float getDistance(Point aPoint) - { - return (float) _p.distance(aPoint); - } - - /** - * Return the straight line distance from this node to aNode or a big - * number if the straight line is known to be blocked - * - * @param aNode - * @return the distance - */ - private float getDistance(Node aNode) - { - if (isBlocked(aNode)) - return BIG; - return getDistance(aNode.getLocation()); - } - - /** - * return the location of this node - * - * @return the location - */ - private Point getLocation() - { - return _p; - } - - /** - * add aNode to list of nodes that are not a neighbour of this Node - * - * @param aNode - */ - private void block(Node aNode) - { - _blocked.add(aNode); - } - - /** - * set the predecessor of this node in the shortest path from the start - * node - * - * @param thePredecessor - */ - private void setPredecessor(Node thePredecessor) - { - _predecessor = thePredecessor; - } - - /** - * get the predecessor of this node in the shortest path from the start - * - * @return the predecessor node - */ - private Node getPredecessor() - { - return _predecessor; - } - - /** - * get the X coordinate of this node - * - * @return X coordinate - */ - private float getX() - { - return (float) _p.getX(); - } - - /** - * get the Y coordinate of the Node - * - * @return Y coordinate - */ - private float getY() - { - return (float) _p.getY(); - } - - public boolean equals(Node n) - { - return this._p.equals(n._p); - } - - public boolean isBlocked(Node aNode) - { - boolean blocked = false; - for (Node n : _blocked) - { - blocked = aNode.equals(n); - if (blocked) - break; - } - return blocked; - } - - @Override - public String toString() - { - return " " + getX() + " , " + getY() + " "; - } - private Point _p; // the location of this SPNode - private float _sourceDistance; - private Node _predecessor; - public ArrayList _blocked = new ArrayList(); - } -} -//**************** end Node class **************************** - - diff --git a/ev3classes/src/main/java/lejos/robotics/pathfinding/package-info.java b/ev3classes/src/main/java/lejos/robotics/pathfinding/package-info.java deleted file mode 100644 index 67f49f8..0000000 --- a/ev3classes/src/main/java/lejos/robotics/pathfinding/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Path finding classes. - */ -package lejos.robotics.pathfinding; diff --git a/ev3classes/src/main/java/lejos/robotics/subsumption/Arbitrator.java b/ev3classes/src/main/java/lejos/robotics/subsumption/Arbitrator.java deleted file mode 100644 index ca7cf90..0000000 --- a/ev3classes/src/main/java/lejos/robotics/subsumption/Arbitrator.java +++ /dev/null @@ -1,151 +0,0 @@ -package lejos.robotics.subsumption; - - -/** - *An Arbitrator object manages a behavior control system by starting and stopping individual behaviors - *
    by the calling the action() and suppress() methods on them. - *
    These Behavior objects are stored in an array, in order of increasing priority. - *
    Arbitrator has three major responsibilities:
    - * 1. Determine the highest priority behavior among those that returns true to takeControl() .
    - * 2. Suppress the active behavior if its priority is less than highest - * priority. These two taska are performed the Arbitrator's internal Monitor thread.
    - * 3. When the action() method exits, call action() on the Behavior of highest priority.
    - * This task is performed by the Arbitrator main thread. - *
    The Arbitrator assumes that a Behavior is no longer active when action() exits, - *
    therefore it will only call suppress() on the active Behavior i.e. whose action() method is running. - *
    It can make consecutive calls of action() on the same Behavior. - *
    Requirements for a Behavior: - *
    When suppress() is called, terminate action() immediately. - *
    When action() exits, the robot is in a safe state (e.g. motors stopped) - *
    When the behavior should take control, the takeControl() should continue to return true - *
    until its action starts. - *
    After your code instantiates the Arbitrator, it should call go() to start it running. - *
    - * @see Behavior - * @author Roger Glassey - */ -public class Arbitrator -{ - - private final int NONE = -1; - private Behavior[] _behavior; - // highest priority behavior that wants control ; set by start() used by monitor - private int _highestPriority = NONE; - private int _active = NONE; // active behavior; set by monitor, used by start(); - private boolean _returnWhenInactive; - public boolean keepRunning = true; - /** - * Monitor is an inner class. It polls the behavior array to find the behavior of hightst - * priority. If higher than the active behavior, it calls active.suppress() - */ - private Monitor monitor; - - /** - * Allocates an Arbitrator object and initializes it with an array of - * Behavior objects. The index of a behavior in this array is its priority level, so - * the behavior of the largest index has the highest the priority level. - * The behaviors in an Arbitrator can not - * be changed once the arbitrator is initialized.
    - * NOTE: Once the Arbitrator is initialized, the method go() must be - * called to begin the arbitration. - * @param behaviorList an array of Behavior objects. - * @param returnWhenInactive if true, the go() method returns when no Behavior is active. - */ - public Arbitrator(Behavior[] behaviorList, boolean returnWhenInactive) - { - _behavior = behaviorList; - _returnWhenInactive = returnWhenInactive; - monitor = new Monitor(); - monitor.setDaemon(true); - System.out.println("Arbitrator created"); - } - - /** - * Same as Arbitrator(behaviorList, false) Arbitrator start() never exits - * @param behaviorList An array of Behavior objects. - */ - public Arbitrator(Behavior[] behaviorList) - { - this(behaviorList, false); - } - - /** - * This method starts the arbitration of Behaviors and runs an endless loop.
    - * Note: Arbitrator does not run in a separate thread. The go() - * method will not return unless
    1. no action() method is running and - *
    2. no behavior takeControl() returns true and - *
    3. the returnWhenInacative flag is true, - */ - public void go() - { - - monitor.start(); - while (_highestPriority == NONE) - { - Thread.yield();//wait for some behavior to take control - } - while (true) - { - synchronized (monitor) - { - if (_highestPriority > NONE) - { - _active = _highestPriority; - } - else if (_returnWhenInactive) - {// no behavior wants to run - monitor.more = false;//9 shut down monitor thread - return; - } - }// monitor released before action is called - if (_active != NONE) //_highestPrioirty could be NONE - { - _behavior[_active].action(); - _active = NONE; // no active behavior at the moment - } - Thread.yield(); - } - } - - public void stop() { - keepRunning = false; - } - - /** - * Finds the highest priority behavior that returns true to takeControl(); - * If this priority is higher than the active behavior, it calls active.suppress(). - */ - private class Monitor extends Thread - { - - boolean more = true; - int maxPriority = _behavior.length - 1; - - public void run() - { - while (keepRunning) - { - //FIND HIGHEST PRIORITY BEHAVIOR THAT WANTS CONTROL - synchronized (this) - { - _highestPriority = NONE; // -1 - for (int i = maxPriority; i > _active; i--) // only behaviors with higher priority are interesting - { - if (_behavior[i].takeControl()) - { - _highestPriority = i; - break; - } - } - int active = _active; // local copy in case _active is set to NONE by the primary thread - if (_active != NONE && _highestPriority > _active) - { - _behavior[active].suppress(); - } - }// end synchronize block - main thread can run now - Thread.yield(); - } - } - } -} - diff --git a/ev3classes/src/main/java/lejos/robotics/subsumption/Behavior.java b/ev3classes/src/main/java/lejos/robotics/subsumption/Behavior.java deleted file mode 100644 index fc2d2f7..0000000 --- a/ev3classes/src/main/java/lejos/robotics/subsumption/Behavior.java +++ /dev/null @@ -1,55 +0,0 @@ -package lejos.robotics.subsumption; - - -/** -* The Behavior interface represents an object embodying a specific -* behavior belonging to a robot. Each behavior must define three things:
    -* 1) The circumstances to make this behavior seize control of the robot. -* e.g. When the touch sensor determines the robot has collided with an object.
    -* 2) The action to perform when this behavior takes control. -* e.g. Back up and turn.
    -* 3) A way to quickly exit from the action when the Arbitrator selects a higher - * priority behavior to take control. -* These are represented by defining the methods takeControl(), action(), -* and suppress() respectively.
    -* A behavior control system has one or more Behavior objects. When you have defined -* these objects, create an array of them and use that array to initialize an -* Arbitrator object. -* -* @see Arbitrator - -* @version 0.9 May 2011 -*/ -public interface Behavior { - - /** - * The boolean return indicates if this behavior should seize control of the robot. - * For example, a robot that reacts if a touch sensor is pressed:
    - * public boolean takeControl() {
    - * return touch.isPressed();
    - * }
    - * @return boolean Indicates if this Behavior should seize control. - */ - public boolean takeControl(); - - /** - * The code in action() represents the tasks the robot performs when this - * behavior becomes active. It can be as complex as navigating around a - * room, or as simple as playing a tune.
    - * The contract for implementing this method is:
    - * If its task is is complete, the method returns. - * It also must return promptly when the suppress() method - * is called, for example by testing the boolean suppress flag.
    - * When this method exits, the robot is in a safe state for another behavior - * to run its action() method - */ - public void action(); - - /** - * The code in suppress() should cause the current behavior to exit.
    - * The contract for implementing this method is:
    - * Exit quickly, for example, just set boolean flag. - */ - public void suppress(); - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/robotics/subsumption/package-info.java b/ev3classes/src/main/java/lejos/robotics/subsumption/package-info.java deleted file mode 100644 index 93f2a53..0000000 --- a/ev3classes/src/main/java/lejos/robotics/subsumption/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Support for subsumption architecture. - */ -package lejos.robotics.subsumption; diff --git a/ev3classes/src/main/java/lejos/utility/DebugMessages.java b/ev3classes/src/main/java/lejos/utility/DebugMessages.java deleted file mode 100644 index 966716d..0000000 --- a/ev3classes/src/main/java/lejos/utility/DebugMessages.java +++ /dev/null @@ -1,128 +0,0 @@ -package lejos.utility; -import lejos.hardware.lcd.LCD; - -/** - * This class has been developed to use it in case of you have - * to tests leJOS programs and you need to show in NXT Display data - * but you don't need to design a User Interface. - * - * This class is very useful to debug algorithms in your NXT brick. - * - * @author Juan Antonio Brenha Moral - * - */ -public class DebugMessages { - private int lineCounter = 0;//Used to know in what row LCD is showing the messages - private final int maximumLCDLines = 7;//NXT Brick has a LCD with 7 lines - private int LCDLines = maximumLCDLines;//By default, Debug Messages show messages in maximumLCDLines - private int delayMS = 250;//By default, the value to establish a delay - private boolean delayEnabled = false;//By default, DebugMessages show messages without any delay - - /* - * Constructors - */ - - /* - * Constructor with default features - */ - public DebugMessages(){ - //Empty - } - - /** - * Constructor which the user establish in what line start showing messages - * - * @param init - */ - public DebugMessages(int init){ - lineCounter = init; - } - - /* - * Getters & Setters - */ - - /** - * Set the number of lines to show in the screen. - * - * @param lines - */ - public void setLCDLines(int lines){ - if(lines <= maximumLCDLines){ - LCDLines = lines; - } - } - - /** - * Enable/Disabled if you need to show output with delay - * - * @param de - */ - public void setDelayEnabled(boolean de){ - delayEnabled = de; - } - - /** - * Set the delay measured in MS. - * - * @param dMs - */ - public void setDelay(int dMs){ - delayMS = dMs; - } - - /* - * Public Methods - */ - - /** - * Show in NXT Screen a message - * - * @param message - */ - public void echo(String message){ - if(lineCounter > LCDLines){ - lineCounter = 0; - LCD.clear(); - }else{ - LCD.drawString(message, 0, lineCounter); - LCD.refresh(); - lineCounter++; - } - if(delayEnabled){ - try {Thread.sleep(delayMS);} catch (Exception e) {} - } - } - - /** - * Show in NXT Screen a message - * - * @param message - */ - public void echo(int message){ - if(lineCounter > LCDLines){ - lineCounter = 0; - LCD.clear(); - }else{ - LCD.drawInt(message, 0, lineCounter); - LCD.refresh(); - lineCounter++; - } - if(delayEnabled){ - try {Thread.sleep(delayMS);} catch (Exception e) {} - } - } - - - /** - * Clear LCD - */ - public void clear(){ - LCD.clear(); - lineCounter = 0; - - if(delayEnabled){ - try {Thread.sleep(delayMS);} catch (Exception e) {} - } - } -} diff --git a/ev3classes/src/main/java/lejos/utility/Delay.java b/ev3classes/src/main/java/lejos/utility/Delay.java deleted file mode 100644 index 1185525..0000000 --- a/ev3classes/src/main/java/lejos/utility/Delay.java +++ /dev/null @@ -1,71 +0,0 @@ -package lejos.utility; - -/** - * Simple collection of time delay routines that are non interruptable. - * @author andy - */ -public class Delay { - - /** - * Wait for the specified number of milliseconds. - * Delays the current thread for the specified period of time. Can not - * be interrupted (but it does preserve the interrupted state). - * @param period time to wait in ms - */ - public static void msDelay(long period) - { - if (period <= 0) return; - long end = System.currentTimeMillis() + period; - boolean interrupted = false; - do { - try { - Thread.sleep(period); - } catch (InterruptedException ie) - { - interrupted = true; - } - period = end - System.currentTimeMillis(); - } while (period > 0); - if (interrupted) - Thread.currentThread().interrupt(); - } - - /** - * Wait for the specified number of microseconds. - * Delays the current thread for the specified period of time. Can not - * be interrupted. - * @param period time to wait in us - */ - public static void usDelay(long period) - { - long end = System.nanoTime() + period*1000; - msDelay(period/1000); - // To improve accuracy for small time periods we use a spin loop. - // Note that we will still have jitter (due to the scheduler, but - // this is probably better than nothing). - while (System.nanoTime() < end) - { - // just spin - } - } - - /** - * Wait for the specified number of nanoseconds. - * Delays the current thread for the specified period of time. Can not - * be interrupted. - * @param period time to wait in ns - */ - public static void nsDelay(long period) - { - long end = System.nanoTime() + period; - msDelay(period/1000000); - // To improve accuracy for small time periods we use a spin loop. - // Note that we will still have jitter (due to the scheduler, but - // this is probably better than nothing). - while (System.nanoTime() < end) - { - // just spin - } - } - -} diff --git a/ev3classes/src/main/java/lejos/utility/EndianTools.java b/ev3classes/src/main/java/lejos/utility/EndianTools.java deleted file mode 100644 index 44bcba9..0000000 --- a/ev3classes/src/main/java/lejos/utility/EndianTools.java +++ /dev/null @@ -1,100 +0,0 @@ -package lejos.utility; - -/** - * Tools for manipulating numbers in little-endian and big-endian encodings - */ -public class EndianTools -{ - public static long decodeLongBE(byte[] b, int off) - { - return ((long) decodeIntBE(b, off) << 32) | (decodeIntBE(b, off + 4) & 0xFFFFFFFFL); - } - - public static long decodeUIntBE(byte[] b, int off) - { - return decodeIntBE(b, off) & 0xFFFFFFFFL; - } - - public static int decodeUShortBE(byte[] b, int off) - { - return decodeShortBE(b, off) & 0xFFFF; - } - - public static int decodeIntBE(byte[] b, int off) - { - return (b[off] << 24) | ((b[off + 1] & 0xFF) << 16) - | ((b[off + 2] & 0xFF) << 8) | (b[off + 3] & 0xFF); - } - - public static short decodeShortBE(byte[] b, int off) - { - return (short) ((b[off] << 8) | (b[off + 1] & 0xFF)); - } - - public static long decodeLongLE(byte[] b, int off) - { - return (decodeIntLE(b, off) & 0xFFFFFFFFL) | ((long) decodeIntLE(b, off + 4) << 32); - } - - public static long decodeUIntLE(byte[] b, int off) - { - return decodeIntLE(b, off) & 0xFFFFFFFFL; - } - - public static int decodeUShortLE(byte[] b, int off) - { - return decodeShortLE(b, off) & 0xFFFF; - } - - public static int decodeIntLE(byte[] b, int off) - { - return (b[off] & 0xFF) | ((b[off + 1] & 0xFF) << 8) - | ((b[off + 2] & 0xFF) << 16) | (b[off + 3] << 24); - } - - public static short decodeShortLE(byte[] b, int off) - { - return (short)((b[off] & 0xFF) | (b[off + 1] << 8)); - } - - public static void encodeLongBE(long v, byte[] b, int off) - { - encodeIntBE((int)(v >>> 32), b, off); - encodeIntBE((int)v, b, off+4); - } - - public static void encodeIntBE(int v, byte[] b, int off) - { - b[off] = (byte)(v >>> 24); - b[off+1] = (byte)(v >>> 16); - b[off+2] = (byte)(v >>> 8); - b[off+3] = (byte)v; - } - - public static void encodeShortBE(int v, byte[] b, int off) - { - b[off] = (byte)(v >>> 8); - b[off+1] = (byte)v; - } - - public static void encodeLongLE(long v, byte[] b, int off) - { - encodeIntLE((int)v, b, off); - encodeIntLE((int)(v >>> 32), b, off+4); - } - - public static void encodeIntLE(int v, byte[] b, int off) - { - b[off] = (byte)v; - b[off+1] = (byte)(v >>> 8); - b[off+2] = (byte)(v >>> 16); - b[off+3] = (byte)(v >>> 24); - } - - public static void encodeShortLE(int v, byte[] b, int off) - { - b[off] = (byte)v; - b[off+1] = (byte)(v >>> 8); - } - -} diff --git a/ev3classes/src/main/java/lejos/utility/GyroDirectionFinder.java b/ev3classes/src/main/java/lejos/utility/GyroDirectionFinder.java deleted file mode 100644 index 3b9db15..0000000 --- a/ev3classes/src/main/java/lejos/utility/GyroDirectionFinder.java +++ /dev/null @@ -1,159 +0,0 @@ -package lejos.utility; - -import lejos.robotics.DirectionFinder; -import lejos.robotics.Gyroscope; - -/** - * Implementation of the DirectionFinder interface that integrates repeated rate-of-turn readings from a - * gyro sensor - * into a continuously updated heading. This class is very similar to the compass sensors, - * except that the direction returned does not convey true heading (north, south, etc) but rather - * relative heading change since the last time setDegrees() or resetCartesianZero() was called. - * @author Brent Gardner - * @author Kirk P. Thompson - */ -public class GyroDirectionFinder implements DirectionFinder -{ - private float cartesianCalibrate = 0; - private float heading = 0; - private float acceleration; - private boolean calibrating = false; - private Regulator reg = new Regulator(); - private Gyroscope gyro; - - /** Creates and initializes a new GyroDirectionFinder using passed GyroSensor - * @param gyro a gyro sensor instance - */ - public GyroDirectionFinder(Gyroscope gyro) { - this(gyro, false); - } - - /** Creates and initializes a new GyroDirectionFinder using passed GyroSensor and does - * the GyroSensor.recalibrateOffset() method. - * @param gyro A gyro sensor instance - */ - public GyroDirectionFinder(Gyroscope gyro, boolean calibrate) { - this.gyro = gyro; - reg.start(); - if(calibrate == false) return; - - // Optional calibration - startCalibration(); - } - - /** - * Resets the current heading to a desired value. - * @see #getDegrees - */ - public void setDegrees(float heading) { - this.heading = heading; - } - - /** - * Returns the directional heading in degrees. Includes "winding", - * so the value could be greater than 360 or less than 0 - * if the robot has done multiple rotations since the last call to resetCartesianZero(). - * @return Heading in degrees. - * @see #setDegrees - */ - public float getDegrees() { - return heading; - } - - /** - * Returns the current rate-of-turn in degrees/second, as read by the GyroSensor instance passed in the constructor. - * @return Angular velocity in degrees. - */ - public float getAngularVelocity() { - return gyro.getAngularVelocity(); - } - - /** - * Returns the current rate at which the angular velocity is increasing or decreasing in degrees-per-second, per second. - * @return Angular acceleration in degrees-per-second per second. - */ - public float getAngularAcceleration() { - return acceleration; - } - - /** - * Returns the current rate-of-turn in degrees, as read by the GyroSensor. - * @return Heading in degrees. - */ - public float getDegreesCartesian() { - return cartesianCalibrate - getDegrees(); - } - - /** - * Resets the current heading to a desired value. - */ - public void setDegreesCartesian(float heading) { - this.heading = cartesianCalibrate - heading; - } - - /** - * Resets the current heading to zero. - */ - public void resetCartesianZero() { - cartesianCalibrate = getDegrees(); - } - - /** - * Find offset/bias of gyro while at rest (ensure it is at rest). This is done by calling the recalibrateOffset() method of - * the GyroSensor instance passed in the constructor. This takes 3 seconds. - */ - public void startCalibration() { - calibrating = true; - Delay.msDelay(2600); - } - - /** - * NO FUNCTIONALITY EQUIVALENT for GyroSensor so implemented just to satisfy the DirectionFinder interface. - * Does nothing. - */ - public void stopCalibration() { - calibrating = false; - } - - /** - * This is the private thread class that is used to continuously integrate successive readings from the gyro - */ - private class Regulator extends Thread { - protected Regulator() { - setDaemon(true); - } - - @Override - public void run() { - float lastDegreesPerSecond = 0F; - float degreesPerSecond, secondsSinceLastReading; - long lastUpdate; - long now = System.currentTimeMillis(); - while (true) { - Delay.msDelay(5); - lastUpdate = now; - now = System.currentTimeMillis(); - - degreesPerSecond=gyro.getAngularVelocity(); - - // Calibration flagged... - if (calibrating) { - gyro.recalibrateOffset(); // 5 seconds consumed here - calibrating = false; - } - - // reduce "perceived" drift since the sensor resolution is 1 deg/sec. This will increase error... - // Comment or remove if this behavior is undesired. I don't know if Brent required a wandering value but - // doing this presents better to the human observer (no perceived drift). KPT 4/7/11 - if (Math.abs(degreesPerSecond)<1.0f) degreesPerSecond=0.0f; - - // Integration - secondsSinceLastReading = (now - lastUpdate) * .001f; - heading += degreesPerSecond * secondsSinceLastReading; - acceleration = (degreesPerSecond - lastDegreesPerSecond) / secondsSinceLastReading; - lastDegreesPerSecond = degreesPerSecond; - } - } - } - -} \ No newline at end of file diff --git a/ev3classes/src/main/java/lejos/utility/Integration.java b/ev3classes/src/main/java/lejos/utility/Integration.java deleted file mode 100644 index 696ae44..0000000 --- a/ev3classes/src/main/java/lejos/utility/Integration.java +++ /dev/null @@ -1,46 +0,0 @@ -package lejos.utility; - -/** - * Integrate sensor measurement over time, e.g. to calculate velocity from acceleration - * or angle from angular velocity. - * - * @author Lawrie Griffiths - * - */ -public class Integration { - private long lastReadingMillis; - private double lastReading; - private double integral; - - /** - * Create the integration object with the initial value for the integral value - * and the initial reading. - * - * @param initialValue the initial value for the integral - * @param reading the initial reading - */ - public Integration(double initialValue, double reading) { - integral = initialValue; - lastReadingMillis = System.currentTimeMillis(); - lastReading = reading; - } - - /** - * Add a new reading and return the current integral - * - * @param reading the reading as a double - * @return the current value of the integral - */ - public double addReading(double reading) { - // Assume linear change between measurements - double averageReading = (reading + lastReading)/2; - long millis = System.currentTimeMillis(); - double timeInterval = (double) (millis - lastReadingMillis) / 1000d; - - lastReadingMillis = millis; - integral += (averageReading * timeInterval); - lastReading = reading; - - return integral; - } -} diff --git a/ev3classes/src/main/java/lejos/utility/KalmanFilter.java b/ev3classes/src/main/java/lejos/utility/KalmanFilter.java deleted file mode 100644 index 30506f6..0000000 --- a/ev3classes/src/main/java/lejos/utility/KalmanFilter.java +++ /dev/null @@ -1,63 +0,0 @@ -package lejos.utility; - -/** - * Implementation of a Kalman filter using the Matrix class - */ -public class KalmanFilter { - private Matrix a, b, c, i, q, r, at, ct; - private Matrix mu, sigma, muBar, sigmaBar, gain; - - public KalmanFilter(Matrix a, Matrix b, Matrix c, Matrix q, Matrix r) { - this.a = a; - this.b = b; - this.c = c; - this.q = q; - this.r = r; - this.at = a.transpose(); - this.ct = c.transpose(); - } - - public void setState(Matrix mean, Matrix covariance) { - this.mu = mean; - this.sigma = covariance; - int n = mu.getRowDimension(); - this.i = Matrix.identity(n, n); - } - - public void update(Matrix control, Matrix measurement) { - // Control update step 1: calculate the predicted mean - muBar = a.times(mu).plus(b.times(control)); - - // Control update step 2: calculate the predicted covariance - sigmaBar = a.times(sigma).times(at).plus(r); - - // Calculate the Kalman Gain - gain = sigmaBar.times(ct).times(c.times(sigmaBar).times(ct).plus(q).inverse()); - - // Measurement update: calculate the new mean - mu = muBar.plus(gain.times(measurement.minus(c.times(muBar)))); - - // Calculate the new covariance - sigma = i.minus(gain.times(c)).times(sigmaBar); - } - - public Matrix getMean() { - return mu; - } - - public Matrix getCovariance() { - return sigma; - } - - public Matrix getPredictedMean() { - return muBar; - } - - public Matrix getPredictedCovariance() { - return sigmaBar; - } - - public Matrix getGain() { - return gain; - } -} diff --git a/ev3classes/src/main/java/lejos/utility/LUDecomposition.java b/ev3classes/src/main/java/lejos/utility/LUDecomposition.java deleted file mode 100644 index 9049b2f..0000000 --- a/ev3classes/src/main/java/lejos/utility/LUDecomposition.java +++ /dev/null @@ -1,313 +0,0 @@ -package lejos.utility; - - /** LU Decomposition. -

    - For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n - unit lower triangular matrix L, an n-by-n upper triangular matrix U, - and a permutation vector piv of length m so that A(piv,:) = L*U. - If m < n, then L is m-by-m and U is m-by-n. -

    - The LU decompostion with pivoting always exists, even if the matrix is - singular, so the constructor will never fail. The primary use of the - LU decomposition is in the solution of square systems of simultaneous - linear equations. This will fail if isNonsingular() returns false. - */ - - public class LUDecomposition implements java.io.Serializable { - - /* ------------------------ - Class variables - * ------------------------ */ - - private static final long serialVersionUID = 1L; - - /** Array for internal storage of decomposition. - @serial internal array storage. - */ - private double[][] LU; - - /** Row and column dimensions, and pivot sign. - @serial column dimension. - @serial row dimension. - @serial pivot sign. - */ - private int m, n, pivsign; - - /** Internal storage of pivot vector. - @serial pivot vector. - */ - private int[] piv; - - /* ------------------------ - Constructor - * ------------------------ */ - - /** LU Decomposition - * - @param A Rectangular matrix - */ - public LUDecomposition (Matrix A) { - - // Use a "left-looking", dot-product, Crout/Doolittle algorithm. - - LU = A.getArrayCopy(); - m = A.getRowDimension(); - n = A.getColumnDimension(); - piv = new int[m]; - for (int i = 0; i < m; i++) { - piv[i] = i; - } - pivsign = 1; - double[] LUrowi; - double[] LUcolj = new double[m]; - - // Outer loop. - - for (int j = 0; j < n; j++) { - - // Make a copy of the j-th column to localize references. - - for (int i = 0; i < m; i++) { - LUcolj[i] = LU[i][j]; - } - - // Apply previous transformations. - - for (int i = 0; i < m; i++) { - LUrowi = LU[i]; - - // Most of the time is spent in the following dot product. - - int kmax = Math.min(i,j); - double s = 0.0; - for (int k = 0; k < kmax; k++) { - s += LUrowi[k]*LUcolj[k]; - } - - LUrowi[j] = LUcolj[i] -= s; - } - - // Find pivot and exchange if necessary. - - int p = j; - for (int i = j+1; i < m; i++) { - if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) { - p = i; - } - } - if (p != j) { - for (int k = 0; k < n; k++) { - double t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t; - } - int k = piv[p]; piv[p] = piv[j]; piv[j] = k; - pivsign = -pivsign; - } - - // Compute multipliers. - - if (j < m & LU[j][j] != 0.0) { - for (int i = j+1; i < m; i++) { - LU[i][j] /= LU[j][j]; - } - } - } - } - - /* ------------------------ - Temporary, experimental code. - ------------------------ *\ - - \** LU Decomposition, computed by Gaussian elimination. -

    - This constructor computes L and U with the "daxpy"-based elimination - algorithm used in LINPACK and MATLAB. In Java, we suspect the dot-product, - Crout algorithm will be faster. We have temporarily included this - constructor until timing experiments confirm this suspicion. -

    - @param A Rectangular matrix - @param linpackflag Use Gaussian elimination. Actual value ignored. - @return Structure to access L, U and piv. - *\ - - public LUDecomposition (Matrix A, int linpackflag) { - // Initialize. - LU = A.getArrayCopy(); - m = A.getRowDimension(); - n = A.getColumnDimension(); - piv = new int[m]; - for (int i = 0; i < m; i++) { - piv[i] = i; - } - pivsign = 1; - // Main loop. - for (int k = 0; k < n; k++) { - // Find pivot. - int p = k; - for (int i = k+1; i < m; i++) { - if (Math.abs(LU[i][k]) > Math.abs(LU[p][k])) { - p = i; - } - } - // Exchange if necessary. - if (p != k) { - for (int j = 0; j < n; j++) { - double t = LU[p][j]; LU[p][j] = LU[k][j]; LU[k][j] = t; - } - int t = piv[p]; piv[p] = piv[k]; piv[k] = t; - pivsign = -pivsign; - } - // Compute multipliers and eliminate k-th column. - if (LU[k][k] != 0.0) { - for (int i = k+1; i < m; i++) { - LU[i][k] /= LU[k][k]; - for (int j = k+1; j < n; j++) { - LU[i][j] -= LU[i][k]*LU[k][j]; - } - } - } - } - } - - \* ------------------------ - End of temporary code. - * ------------------------ */ - - /* ------------------------ - Public Methods - * ------------------------ */ - - /** Is the matrix nonsingular? - @return true if U, and hence A, is nonsingular. - */ - - public boolean isNonsingular () { - for (int j = 0; j < n; j++) { - if (LU[j][j] == 0) - return false; - } - return true; - } - - /** Return lower triangular factor - @return L - */ - - public Matrix getL () { - Matrix X = new Matrix(m,n); - double[][] L = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - if (i > j) { - L[i][j] = LU[i][j]; - } else if (i == j) { - L[i][j] = 1.0; - } else { - L[i][j] = 0.0; - } - } - } - return X; - } - - /** Return upper triangular factor - @return U - */ - - public Matrix getU () { - Matrix X = new Matrix(n,n); - double[][] U = X.getArray(); - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (i <= j) { - U[i][j] = LU[i][j]; - } else { - U[i][j] = 0.0; - } - } - } - return X; - } - - /** Return pivot permutation vector - @return piv - */ - - public int[] getPivot () { - int[] p = new int[m]; - for (int i = 0; i < m; i++) { - p[i] = piv[i]; - } - return p; - } - - /** Return pivot permutation vector as a one-dimensional double array - @return (double) piv - */ - - public double[] getDoublePivot () { - double[] vals = new double[m]; - for (int i = 0; i < m; i++) { - vals[i] = (double) piv[i]; - } - return vals; - } - - /** Determinant - @return det(A) - @exception IllegalArgumentException Matrix must be square - */ - - public double det () { - if (m != n) { - throw new IllegalArgumentException("Matrix must be square."); - } - double d = (double) pivsign; - for (int j = 0; j < n; j++) { - d *= LU[j][j]; - } - return d; - } - - /** Solve A*X = B - @param B A Matrix with as many rows as A and any number of columns. - @return X so that L*U*X = B(piv,:) - @exception IllegalArgumentException Matrix row dimensions must agree. - @exception RuntimeException Matrix is singular. - */ - - public Matrix solve (Matrix B) { - if (B.getRowDimension() != m) { - throw new IllegalArgumentException("Matrix row dimensions must agree."); - } - if (!this.isNonsingular()) { - throw new RuntimeException("Matrix is singular."); - } - - // Copy right hand side with pivoting - int nx = B.getColumnDimension(); - Matrix Xmat = B.getMatrix(piv,0,nx-1); - double[][] X = Xmat.getArray(); - - // Solve L*Y = B(piv,:) - for (int k = 0; k < n; k++) { - for (int i = k+1; i < n; i++) { - for (int j = 0; j < nx; j++) { - X[i][j] -= X[k][j]*LU[i][k]; - } - } - } - // Solve U*X = Y; - for (int k = n-1; k >= 0; k--) { - for (int j = 0; j < nx; j++) { - X[k][j] /= LU[k][k]; - } - for (int i = 0; i < k; i++) { - for (int j = 0; j < nx; j++) { - X[i][j] -= X[k][j]*LU[i][k]; - } - } - } - return Xmat; - } -} - diff --git a/ev3classes/src/main/java/lejos/utility/Matrix.java b/ev3classes/src/main/java/lejos/utility/Matrix.java deleted file mode 100644 index 802766c..0000000 --- a/ev3classes/src/main/java/lejos/utility/Matrix.java +++ /dev/null @@ -1,817 +0,0 @@ -package lejos.utility; - -import java.io.PrintStream; - -/** - * Matrix implementation derived from the JAMA project - */ -public class Matrix implements Cloneable, java.io.Serializable { - -/* ------------------------ - Class variables - * ------------------------ */ - - private static final long serialVersionUID = 5724948160773341967L; - -/** Array for internal storage of elements. - @serial internal array storage. - */ - private double[][] A; - - /** Row and column dimensions. - @serial row dimension. - @serial column dimension. - */ - private int m, n; - -/* ------------------------ - Constructors - * ------------------------ */ - - /** Construct an m-by-n matrix of zeros. - @param m Number of rows. - @param n Number of columns. - */ - - public Matrix (int m, int n) { - this.m = m; - this.n = n; - A = new double[m][n]; - } - - /** Construct an m-by-n constant matrix. - @param m Number of rows. - @param n Number of columns. - @param s Fill the matrix with this scalar value. - */ - - public Matrix (int m, int n, double s) { - this.m = m; - this.n = n; - A = new double[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = s; - } - } - } - - /** Construct a matrix from a 2-D array. - @param A Two-dimensional array of doubles. - @exception IllegalArgumentException All rows must have the same length - @see #constructWithCopy - */ - - public Matrix (double[][] A) throws IllegalArgumentException{ - m = A.length; - n = A[0].length; - for (int i = 0; i < m; i++) { - if (A[i].length != n) { - throw new IllegalArgumentException("All rows must have the same length."); - } - } - this.A = A; - } - - /** Construct a matrix quickly without checking arguments. - @param A Two-dimensional array of doubles. - @param m Number of rows. - @param n Number of colums. - */ - - public Matrix (double[][] A, int m, int n) { - this.A = A; - this.m = m; - this.n = n; - } - - /** Construct a matrix from a one-dimensional packed array - @param vals One-dimensional array of doubles, packed by columns (ala Fortran). - @param m Number of rows. - @exception IllegalArgumentException Array length must be a multiple of m. - */ - - public Matrix (double vals[], int m) throws IllegalArgumentException { - this.m = m; - n = (m != 0 ? vals.length/m : 0); - if (m*n != vals.length) { - throw new IllegalArgumentException("Array length must be a multiple of m."); - } - A = new double[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = vals[i+j*m]; - } - } - } - -/* ------------------------ - Public Methods - * ------------------------ */ - - /** Construct a matrix from a copy of a 2-D array. - @param A Two-dimensional array of doubles. - @exception IllegalArgumentException All rows must have the same length - */ - - public static Matrix constructWithCopy(double[][] A) throws IllegalArgumentException{ - int m = A.length; - int n = A[0].length; - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - if (A[i].length != n) { - throw new IllegalArgumentException("All rows must have the same length."); - } - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j]; - } - } - return X; - } - - /** Make a deep copy of a matrix - */ - - public Matrix copy () { - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j]; - } - } - return X; - } - - /** Clone the Matrix object. - */ - - @Override - public Object clone () { - return this.copy(); - } - - /** Access the internal two-dimensional array. - @return Pointer to the two-dimensional array of matrix elements. - */ - - public double[][] getArray () { - return A; - } - - /** Copy the internal two-dimensional array. - @return Two-dimensional array copy of matrix elements. - */ - - public double[][] getArrayCopy () { - double[][] C = new double[m][n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j]; - } - } - return C; - } - - /** Make a one-dimensional column packed copy of the internal array. - @return Matrix elements packed in a one-dimensional array by columns. - */ - - public double[] getColumnPackedCopy () { - double[] vals = new double[m*n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - vals[i+j*m] = A[i][j]; - } - } - return vals; - } - - /** Make a one-dimensional row packed copy of the internal array. - @return Matrix elements packed in a one-dimensional array by rows. - */ - - public double[] getRowPackedCopy () { - double[] vals = new double[m*n]; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - vals[i*n+j] = A[i][j]; - } - } - return vals; - } - - /** Get row dimension. - @return m, the number of rows. - */ - - public int getRowDimension () { - return m; - } - - /** Get column dimension. - @return n, the number of columns. - */ - - public int getColumnDimension () { - return n; - } - - /** Get a single element. - @param i Row index. - @param j Column index. - @return A(i,j) - */ - - public double get (int i, int j) { - return A[i][j]; - } - - /** Get a submatrix. - @param i0 Initial row index - @param i1 Final row index - @param j0 Initial column index - @param j1 Final column index - @return A(i0:i1,j0:j1) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public Matrix getMatrix (int i0, int i1, int j0, int j1) throws ArrayIndexOutOfBoundsException{ - Matrix X = new Matrix(i1-i0+1,j1-j0+1); - double[][] B = X.getArray(); - try { - for (int i = i0; i <= i1; i++) { - for (int j = j0; j <= j1; j++) { - B[i-i0][j-j0] = A[i][j]; - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - return X; - } - - /** Get a submatrix. - @param r Array of row indices. - @param c Array of column indices. - @return A(r(:),c(:)) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public Matrix getMatrix (int[] r, int[] c) throws ArrayIndexOutOfBoundsException{ - Matrix X = new Matrix(r.length,c.length); - double[][] B = X.getArray(); - try { - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { - B[i][j] = A[r[i]][c[j]]; - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - return X; - } - - /** Get a submatrix. - @param i0 Initial row index - @param i1 Final row index - @param c Array of column indices. - @return A(i0:i1,c(:)) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public Matrix getMatrix (int i0, int i1, int[] c) throws ArrayIndexOutOfBoundsException{ - Matrix X = new Matrix(i1-i0+1,c.length); - double[][] B = X.getArray(); - try { - for (int i = i0; i <= i1; i++) { - for (int j = 0; j < c.length; j++) { - B[i-i0][j] = A[i][c[j]]; - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - return X; - } - - /** Get a submatrix. - @param r Array of row indices. - @param j0 Initial column index - @param j1 Final column index - @return A(r(:),j0:j1) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public Matrix getMatrix (int[] r, int j0, int j1) throws ArrayIndexOutOfBoundsException{ - Matrix X = new Matrix(r.length,j1-j0+1); - double[][] B = X.getArray(); - try { - for (int i = 0; i < r.length; i++) { - for (int j = j0; j <= j1; j++) { - B[i][j-j0] = A[r[i]][j]; - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - return X; - } - - /** Set a single element. - @param i Row index. - @param j Column index. - @param s A(i,j). - @exception ArrayIndexOutOfBoundsException - */ - - public void set (int i, int j, double s) { - A[i][j] = s; - } - - /** Set a submatrix. - @param i0 Initial row index - @param i1 Final row index - @param j0 Initial column index - @param j1 Final column index - @param X A(i0:i1,j0:j1) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public void setMatrix (int i0, int i1, int j0, int j1, Matrix X) throws ArrayIndexOutOfBoundsException{ - try { - for (int i = i0; i <= i1; i++) { - for (int j = j0; j <= j1; j++) { - A[i][j] = X.get(i-i0,j-j0); - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - } - - /** Set a submatrix. - @param r Array of row indices. - @param c Array of column indices. - @param X A(r(:),c(:)) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public void setMatrix (int[] r, int[] c, Matrix X) throws ArrayIndexOutOfBoundsException{ - try { - for (int i = 0; i < r.length; i++) { - for (int j = 0; j < c.length; j++) { - A[r[i]][c[j]] = X.get(i,j); - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - } - - /** Set a submatrix. - @param r Array of row indices. - @param j0 Initial column index - @param j1 Final column index - @param X A(r(:),j0:j1) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public void setMatrix (int[] r, int j0, int j1, Matrix X) throws ArrayIndexOutOfBoundsException{ - try { - for (int i = 0; i < r.length; i++) { - for (int j = j0; j <= j1; j++) { - A[r[i]][j] = X.get(i,j-j0); - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - } - - /** Set a submatrix. - @param i0 Initial row index - @param i1 Final row index - @param c Array of column indices. - @param X A(i0:i1,c(:)) - @exception ArrayIndexOutOfBoundsException Submatrix indices - */ - - public void setMatrix (int i0, int i1, int[] c, Matrix X) throws ArrayIndexOutOfBoundsException{ - try { - for (int i = i0; i <= i1; i++) { - for (int j = 0; j < c.length; j++) { - A[i][c[j]] = X.get(i-i0,j); - } - } - } catch(ArrayIndexOutOfBoundsException e) { - throw new ArrayIndexOutOfBoundsException("Submatrix indices"); - } - } - - /** Matrix transpose. - @return A' - */ - - public Matrix transpose () { - Matrix X = new Matrix(n,m); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[j][i] = A[i][j]; - } - } - return X; - } - - /** One norm - @return maximum column sum. - */ - - public double norm1 () { - double f = 0; - for (int j = 0; j < n; j++) { - double s = 0; - for (int i = 0; i < m; i++) { - s += Math.abs(A[i][j]); - } - f = Math.max(f,s); - } - return f; - } - - - /** Infinity norm - @return maximum row sum. - */ - - public double normInf () { - double f = 0; - for (int i = 0; i < m; i++) { - double s = 0; - for (int j = 0; j < n; j++) { - s += Math.abs(A[i][j]); - } - f = Math.max(f,s); - } - return f; - } - - /** Frobenius norm - @return sqrt of sum of squares of all elements. - */ - - public double normF () { - double f = 0; - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - f = hypot(f,A[i][j]); - } - } - return f; - } - - /** Unary minus - @return -A - */ - - public Matrix uminus () { - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = -A[i][j]; - } - } - return X; - } - - /** C = A + B - @param B another matrix - @return A + B - */ - - public Matrix plus (Matrix B) { - checkMatrixDimensions(B); - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] + B.A[i][j]; - } - } - return X; - } - - /** A = A + B - @param B another matrix - @return A + B - */ - - public Matrix plusEquals (Matrix B) { - checkMatrixDimensions(B); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = A[i][j] + B.A[i][j]; - } - } - return this; - } - - /** C = A - B - @param B another matrix - @return A - B - */ - - public Matrix minus (Matrix B) { - checkMatrixDimensions(B); - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] - B.A[i][j]; - } - } - return X; - } - - /** A = A - B - @param B another matrix - @return A - B - */ - - public Matrix minusEquals (Matrix B) { - checkMatrixDimensions(B); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = A[i][j] - B.A[i][j]; - } - } - return this; - } - - /** Element-by-element multiplication, C = A.*B - @param B another matrix - @return A.*B - */ - - public Matrix arrayTimes (Matrix B) { - checkMatrixDimensions(B); - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] * B.A[i][j]; - } - } - return X; - } - - - /** - * - */ - public Matrix arrayTimesEquals (Matrix B) { - checkMatrixDimensions(B); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = A[i][j] * B.A[i][j]; - } - } - return this; - } - - /** Element-by-element right division, C = A./B - @param B another matrix - @return A./B - */ - - public Matrix arrayRightDivide (Matrix B) { - checkMatrixDimensions(B); - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] / B.A[i][j]; - } - } - return X; - } - - /** Element-by-element right division in place, A = A./B - @param B another matrix - @return A./B - */ - - public Matrix arrayRightDivideEquals (Matrix B) { - checkMatrixDimensions(B); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = A[i][j] / B.A[i][j]; - } - } - return this; - } - - /** Element-by-element left division, C = A.\B - @param B another matrix - @return A.\B - */ - - public Matrix arrayLeftDivide (Matrix B) { - checkMatrixDimensions(B); - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = B.A[i][j] / A[i][j]; - } - } - return X; - } - - /** Element-by-element left division in place, A = A.\B - @param B another matrix - @return A.\B - */ - - public Matrix arrayLeftDivideEquals (Matrix B) { - checkMatrixDimensions(B); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = B.A[i][j] / A[i][j]; - } - } - return this; - } - - /** Multiply a matrix by a scalar, C = s*A - @param s scalar - @return s*A - */ - - public Matrix times (double s) { - Matrix X = new Matrix(m,n); - double[][] C = X.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - C[i][j] = s*A[i][j]; - } - } - return X; - } - - /** Multiply a matrix by a scalar in place, A = s*A - @param s scalar - @return replace A by s*A - */ - - public Matrix timesEquals (double s) { - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - A[i][j] = s*A[i][j]; - } - } - return this; - } - - /** Linear algebraic matrix multiplication, A * B - @param B another matrix - @return Matrix product, A * B - @exception IllegalArgumentException Matrix inner dimensions must agree. - */ - - public Matrix times (Matrix B) throws IllegalArgumentException{ - if (B.m != n) { - throw new IllegalArgumentException("Matrix inner dimensions must agree."); - } - Matrix X = new Matrix(m,B.n); - double[][] C = X.getArray(); - double[] Bcolj = new double[n]; - for (int j = 0; j < B.n; j++) { - for (int k = 0; k < n; k++) { - Bcolj[k] = B.A[k][j]; - } - for (int i = 0; i < m; i++) { - double[] Arowi = A[i]; - double s = 0; - for (int k = 0; k < n; k++) { - s += Arowi[k]*Bcolj[k]; - } - C[i][j] = s; - } - } - return X; - } - - - /** Matrix trace. - @return sum of the diagonal elements. - */ - - public double trace () { - double t = 0; - for (int i = 0; i < Math.min(m,n); i++) { - t += A[i][i]; - } - return t; - } - - /** Generate matrix with random elements - @param m Number of rows. - @param n Number of colums. - @return An m-by-n matrix with uniformly distributed random elements. - */ - - public static Matrix random (int m, int n) { - Matrix A = new Matrix(m,n); - double[][] X = A.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - X[i][j] = Math.random(); - } - } - return A; - } - - /** Generate identity matrix - @param m Number of rows. - @param n Number of colums. - @return An m-by-n matrix with ones on the diagonal and zeros elsewhere. - */ - - public static Matrix identity (int m, int n) { - Matrix A = new Matrix(m,n); - double[][] X = A.getArray(); - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - X[i][j] = (i == j ? 1.0 : 0.0); - } - } - return A; - } - - /** Matrix inverse or pseudoinverse - @return inverse(A) if A is square, pseudoinverse otherwise. - */ - - public Matrix inverse () { - return solve(identity(m,m)); - } - - /** Solve A*X = B - @param B right hand side - @return solution if A is square, least squares solution otherwise - */ - - public Matrix solve (Matrix B) { - // leJOS package only supports square matrices - return new LUDecomposition(this).solve(B); - } - /* - * Simple version of Matrix print - */ - public void print(PrintStream out) { - for(int i=0;i Math.abs(b)) { - r = b/a; - r = Math.abs(a)*Math.sqrt(1+r*r); - } else if (b != 0) { - r = a/b; - r = Math.abs(b)*Math.sqrt(1+r*r); - } else { - r = 0.0; - } - return r; - } -} diff --git a/ev3classes/src/main/java/lejos/utility/PilotProps.java b/ev3classes/src/main/java/lejos/utility/PilotProps.java deleted file mode 100644 index abda3ea..0000000 --- a/ev3classes/src/main/java/lejos/utility/PilotProps.java +++ /dev/null @@ -1,75 +0,0 @@ -package lejos.utility; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; - -import lejos.hardware.motor.Motor; -import lejos.robotics.RegulatedMotor; - -/** - * Configuration class for Differential Pilot. - * - * @author Lawrie Griffiths - * - */ -public class PilotProps extends Properties -{ - public static final String PERSISTENT_FILENAME = "pilot.props"; - - public static final String KEY_WHEELDIAMETER = "wheelDiameter"; - public static final String KEY_TRACKWIDTH = "trackWidth"; - public static final String KEY_LEFTMOTOR = "leftMotor"; - public static final String KEY_RIGHTMOTOR = "rightMotor"; - public static final String KEY_REVERSE = "reverse"; - - public void loadPersistentValues() throws IOException - { - File f = new File(PERSISTENT_FILENAME); - if (!f.exists()) - return; - - FileInputStream fis = new FileInputStream(f); - try - { - this.load(fis); - } - finally - { - fis.close(); - } - } - - public void storePersistentValues() throws IOException - { - File f = new File(PERSISTENT_FILENAME); - FileOutputStream fos = new FileOutputStream(f); - try - { - this.store(fos, null); - } - finally - { - fos.close(); - } - } - - /** - * 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 - return null; - } -} diff --git a/ev3classes/src/main/java/lejos/utility/SensorSelector.java b/ev3classes/src/main/java/lejos/utility/SensorSelector.java deleted file mode 100644 index af3e1d9..0000000 --- a/ev3classes/src/main/java/lejos/utility/SensorSelector.java +++ /dev/null @@ -1,48 +0,0 @@ -package lejos.utility; - -import lejos.hardware.device.IRLink; -import lejos.hardware.device.IRTransmitter; -import lejos.hardware.device.RCXLink; -import lejos.hardware.port.I2CPort; -import lejos.hardware.sensor.HiTechnicAccelerometer; -import lejos.hardware.sensor.I2CSensor; -import lejos.hardware.sensor.MindsensorsAccelerometer; -import lejos.hardware.sensor.SensorMode; - -/** - * Factory for I2C sensor implementations. - * Tests what make of sensor is connected to a port and creates - * an instance of the appropriate class for a given sensor interface. - * - * @author Lawrie Griffiths - * - */ -public class SensorSelector { - - private static final String MINDSENSORS_ID = "mndsnsrs"; - private static final String HITECHNIC_ID = "hitechnc"; - - public static SensorMode createAccelerometer(I2CPort port) throws SensorSelectorException { - I2CSensor tester = new I2CSensor(port); - String type = tester.getVendorID().toLowerCase(); - - if (type.equals(MINDSENSORS_ID)) - return new MindsensorsAccelerometer(port).getAccelerationMode(); - if (type.equals(HITECHNIC_ID)) - return new HiTechnicAccelerometer(port).getAccelerationMode(); - - throw new SensorSelectorException("No Such Sensor"); - } - - public static IRTransmitter createIRTransmitter(I2CPort port) throws SensorSelectorException { - I2CSensor tester = new I2CSensor(port); - String type = tester.getVendorID().toLowerCase(); - - if (type.equals(MINDSENSORS_ID)) - return new RCXLink(port); - if (type.equals(HITECHNIC_ID)) - return new IRLink(port); - - throw new SensorSelectorException("No Such Sensor"); - } -} diff --git a/ev3classes/src/main/java/lejos/utility/SensorSelectorException.java b/ev3classes/src/main/java/lejos/utility/SensorSelectorException.java deleted file mode 100644 index be2b5a9..0000000 --- a/ev3classes/src/main/java/lejos/utility/SensorSelectorException.java +++ /dev/null @@ -1,9 +0,0 @@ -package lejos.utility; - -public class SensorSelectorException extends Exception { - - public SensorSelectorException(String message) { - super(message); - } - -} diff --git a/ev3classes/src/main/java/lejos/utility/Stopwatch.java b/ev3classes/src/main/java/lejos/utility/Stopwatch.java deleted file mode 100644 index d67119a..0000000 --- a/ev3classes/src/main/java/lejos/utility/Stopwatch.java +++ /dev/null @@ -1,30 +0,0 @@ -package lejos.utility; - -/** -* Elapsed time watch (in milliseconds)
    -* To use - construct a new instance. -* @author Roger Glassey -* version 2 -*/ -public class Stopwatch -{ -/** -records system clock time (in milliseconds) when reset() was executed -*/ - private int t0 = (int)System.currentTimeMillis(); - -/** -Reset watch to zero -*/ - public void reset() - { - t0 = (int)System.currentTimeMillis(); - } -/** -Return elapsed time in milliseconds -*/ - public int elapsed( ) - { - return (int)System.currentTimeMillis() -t0; - } -} diff --git a/ev3classes/src/main/java/lejos/utility/TextMenu.java b/ev3classes/src/main/java/lejos/utility/TextMenu.java deleted file mode 100644 index d3e89d1..0000000 --- a/ev3classes/src/main/java/lejos/utility/TextMenu.java +++ /dev/null @@ -1,278 +0,0 @@ -package lejos.utility; - -import lejos.hardware.BrickFinder; -import lejos.hardware.Button; -import lejos.hardware.lcd.TextLCD; - -/** - *Displays a list of items. The select() method allows the user to scroll the list using the right and left keys to scroll forward and backward - * through the list. The location of the list , and an optional title can be specified. - * @author Roger Glassey Feb 20, 2007 - */ - -public class TextMenu -{ - /** - *location of the top row of the list; set by constructor, used by display() - */ - protected int _topRow = 0; - - /** - * number of rows displayed; set by constructor, used by display() - */ - protected int _height = 8; - - /** - *optional menu title displayed immediately above the list of items - */ - protected String _title; - - /** - *array of items to be displayed ;set by constructor, used by select(); - */ - protected String[] _items; - - /** - * effective length of items array - number of items before null - */ - protected int _length; - - /** - * index of the list item at the top of the list; set by constructor, used by select() - **/ - protected int _topIndex = 0; - - /** - *identifies the currently selected item - */ - protected static final char SEL_CHAR = '>'; - - /** - * boolean to cause select to quit - */ - protected boolean _quit = false; - - /** - * start time for select() - */ - protected int _startTime; - - /** - * Timout used for {@link Button#waitForAnyPress(int)} in {@link #select(int, int)}. - */ - protected static final int BUTTON_POLL_INTERVAL = 10; // Time to wait for button press - - protected TextLCD lcd = BrickFinder.getDefault().getTextLCD(); - - /** - * This constructor sets location of the top row of the item list to row 0 of the display. - */ - public TextMenu( String[] items) - { - this(items, 0, null); - } - - /** - * This constructor allows specification location of the item list . - */ - public TextMenu( String[] items, int topRow) - { - this(items, topRow, null); - } - - /** - * This constuctor allows the specfication of a title (of up to 16 characters) and the location of the item list
    - * The title is displayed in the row above the item list. - * @param items - string array containing the menu items. No items beyond the first null will be displayed. - */ - public TextMenu(String[] items, int topRow, String title) - { - if (topRow < 0 || (topRow == 0 && title != null)) - throw new IllegalArgumentException("illegal topRow argument"); - - _topRow = topRow; - setTitle(title); - this.setItems(items); - } - - /** - * set menu title. - * @param title the new title - */ - public void setTitle(String title) - { - _title = title; - if(_topRow <= 0) - _topRow = 1; - _height = 8 - _topRow; - if(_height > _length) - _height = _length; - } - - /** - * set the array of items to be displayed - * @param items - */ - public void setItems(String[] items) - { - _items = items; - - if (items == null) - _length = 0; - else - { - int i = 0; - while(i < items.length && items[i] != null) - i++; - _length = i; - } - _height = 8 - _topRow; - if(_height > _length) - _height = _length; - } - - /** - * Allows the user to scroll through the items, using the right and left buttons (forward and back) The Enter key closes the menu
    - * and returns the index of the selected item.
    - * The menu display wraps items that scroll off the top will reappear on the bottom and vice versa. - * - * The selectedIndex is set to the first menu item. - * - * @return the index of the selected item - **/ - public int select() - { - return select(0,0); - } - - /** - * Version of select without timeout - */ - public int select(int selectedIndex) { - return select(selectedIndex, 0); - } - - /** - * Allows the user to scroll through the items, using the right and left buttons (forward and back) The Enter key closes the menu
    - * and returns the index of the selected item.
    - * The menu display wraps items that scroll off the top will reappear on the bottom and vice versa. - * - * This version of select allows the selected index to be set when the menu is first displayed. - * - * @param selectedIndex the index to start the menu on - * @return the index of the selected item - **/ - public int select(int selectedIndex, int timeout) - { - if (selectedIndex >= _length) - //might result in -1 - selectedIndex = _length -1; - if (selectedIndex < 0) - selectedIndex = 0; - -// if (_length<_size) _size = _length; - _quit = false; - resetTimeout(); -// LCD.clear(); - if (_topIndex > selectedIndex) - _topIndex = selectedIndex; - if (_topIndex > _length - _height) - _topIndex = _length - _height; - display(selectedIndex, _topIndex); - while(true) - { - int button; - do - { - if (_quit) - return -2; // quit by another thread - - if (timeout > 0 && System.currentTimeMillis() - _startTime >= timeout) - return -3; // timeout - - button = Button.waitForAnyPress(BUTTON_POLL_INTERVAL); - } while (button == 0); - - if(button == Button.ID_ENTER && selectedIndex >= 0 && selectedIndex < _length) - return selectedIndex; - if(button == Button.ID_ESCAPE) - return -1; //Escape - if(button == Button.ID_DOWN)//scroll forward - { - selectedIndex++; - // check for index out of bounds - if(selectedIndex >= _length) - { - selectedIndex = 0; - _topIndex = 0; - } - else if(selectedIndex >= _topIndex + _height) - { - _topIndex = selectedIndex - _height + 1; - } - } - if(button == Button.ID_UP)//scroll backward - { - selectedIndex --; - // check for index out of bounds - if(selectedIndex < 0) - { - selectedIndex = _length - 1; - _topIndex = _length - _height; - } - else if(selectedIndex < _topIndex) - { - _topIndex = selectedIndex; - } - } - display(selectedIndex, _topIndex); - } - } - - /** - * method to call from another thread to quit the menu - */ - public void quit() - { - _quit = true; - } - - /** - * helper method used by select() - */ - protected void display(int selectedIndex, int topIndex) - { - //LCD.asyncRefreshWait(); - if(_title != null) - lcd.drawString(_title, 0, _topRow - 1); - int max = _topRow + _height; - for (int i = _topRow; i < max; i++) - { - lcd.clear(i); - int idx = i - _topRow + topIndex; - if (idx >= 0 && idx < _length) - { - lcd.drawChar(idx == selectedIndex ? SEL_CHAR : ' ', 0, i); - lcd.drawString(_items[idx], 1, i); - } - } - lcd.refresh(); - } - - /** - * Returns list of items in this menu; - * @return the array of item names - */ - public String[] getItems() - { - return _items; - } - - /** - * Reset the timeout period. - */ - public void resetTimeout() { - _startTime = (int) System.currentTimeMillis(); - } -} - diff --git a/ev3classes/src/main/java/lejos/utility/Timer.java b/ev3classes/src/main/java/lejos/utility/Timer.java deleted file mode 100644 index 236fb92..0000000 --- a/ev3classes/src/main/java/lejos/utility/Timer.java +++ /dev/null @@ -1,82 +0,0 @@ -package lejos.utility; - - -/** - * Timer object, with some similar functionality to java.Swing.Timer. - * - * @author Ryan VanderBijl - */ -public class Timer -{ - private TimerListener myListener; - private Thread myThread ; - private int delay ; - private boolean running ; - - /** - * Create a Timer object. Every theDelay milliseconds - * the el.timedOut() function is called. You may - * change the delay with setDelay(int). You need - * to call start() explicitly. - */ - public Timer(int theDelay, TimerListener el) - { - running = false; - delay = theDelay; - myListener = el; - - myThread = new Thread() { - public void run() { - int d; - boolean r; - while(true) { - synchronized(Timer.this) - { - d = delay; - r = running; - } - if (r) - { - Delay.msDelay(d); - myListener.timedOut(); - } else { - yield(); - } - } - } - }; - - myThread.setDaemon(true); - } - - /** - * access how man milliseconds between timedOut() messages. - */ - public synchronized int getDelay() { - return delay; - } - /** - * Change the delay between timedOut messages. Safe to call - * while start()ed. Time in milli-seconds. - */ - public synchronized void setDelay(int newDelay) { - delay = newDelay; - } - - /** - * Stops the timer. timedOut() messages are not sent. - */ - public synchronized void stop() { - running = false; - } - - /** - * Starts the timer, telling it to send timeOut() methods - * to the TimerListener. - */ - public synchronized void start() { - running = true; - if (!myThread.isAlive()) - myThread.start(); - } -} diff --git a/ev3classes/src/main/java/lejos/utility/TimerListener.java b/ev3classes/src/main/java/lejos/utility/TimerListener.java deleted file mode 100644 index ea860e4..0000000 --- a/ev3classes/src/main/java/lejos/utility/TimerListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package lejos.utility; - - -/** - * Listener used with Timer. - * - * @see lejos.utility.Timer - * @author Ryan VanderBijl - */ - -public interface TimerListener -{ - /** - * Called every time the Timer fires. - */ - public void timedOut(); -} diff --git a/ev3classes/src/main/java/lejos/utility/package-info.java b/ev3classes/src/main/java/lejos/utility/package-info.java deleted file mode 100644 index 81e37e5..0000000 --- a/ev3classes/src/main/java/lejos/utility/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * More utility classes - */ -package lejos.utility; diff --git a/gradle.properties b/gradle.properties index e69de29..5d7ed1c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -0,0 +1,3 @@ +brick_user = root +brick_host = 192.168.0.104 +brick_home = /home/lejos/programs diff --git a/samples/build.gradle b/samples/build.gradle index 6f0568f..4763e90 100644 --- a/samples/build.gradle +++ b/samples/build.gradle @@ -1,5 +1,82 @@ +apply plugin: Mindstorms + dependencies { + compile 'com.google.guava:guava:19.0' +} + +mindstorms { + main = 'com.github.bdeneuter.mindstorms.samples.HelloWorld' +} + +class Mindstorms implements Plugin { + void apply(Project project) { + project.extensions.create("mindstorms", MindstormsExtension) + project.configure(project) { + + apply plugin: 'java' + + sourceCompatibility = 1.8 + targetCompatibility = 1.8 + + repositories { + mavenCentral() + } + + configurations { + scp + } + + dependencies { + compileOnly 'com.github.bdeneuter:lejos-ev3-api:0.9.1-beta' + scp 'org.apache.ant:ant-jsch:1.9.4' + } + + jar { + + from { + (configurations.runtime).collect { + it.isDirectory() ? it : zipTree(it) + } + } + + manifest { + attributes('Class-Path': + 'home/root/lejos/lib/ev3classes.jar ' + + '/home/root/lejos/lib/dbusjava.jar ' + + '/home/root/lejos/libjna/usr/share/java/jna.jar', + 'Main-Class': "${project.mindstorms.main}") + } + } + + project.task(dependsOn: 'assemble', 'copyToRobot') << { + + ant.taskdef( + name: 'scp', + classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp', + classpath: configurations.scp.asPath) + + new File(buildDir, 'libs') + .listFiles() + .findAll { it.name.endsWith '.jar' } + .each { + ant.scp( + file: it, + todir: brick_user + '@' + brick_host + ':' + brick_home, + username: brick_user, + password: '', + trust: true + ) + } + + } + + } + + } +} + +class MindstormsExtension { - compileOnly project(":ev3classes") + String main; -} \ No newline at end of file +} diff --git a/samples/build.gradle.bck b/samples/build.gradle.bck new file mode 100644 index 0000000..3403256 --- /dev/null +++ b/samples/build.gradle.bck @@ -0,0 +1,42 @@ +plugins { + id 'com.github.johnrengelman.shadow' version '1.2.3' +} + +configurations { + scp +} + +dependencies { + compileOnly 'com.github.bdeneuter:lejos-ev3-api:0.9.1-beta' + scp 'org.apache.ant:ant-jsch:1.9.4' +} + +jar { + manifest { + attributes('Class-Path': + 'home/root/lejos/lib/ev3classes.jar ' + + '/home/root/lejos/lib/dbusjava.jar ' + + '/home/root/lejos/libjna/usr/share/java/jna.jar', + 'Main-Class': 'com.github.bdeneuter.mindstorms.samples.HelloWorld') + } +} + +assemble.dependsOn shadowJar + +task copyToRobot(dependsOn: 'assemble') { + doLast { + + ant.taskdef( + name: 'scp', + classname: 'org.apache.tools.ant.taskdefs.optional.ssh.Scp', + classpath: configurations.scp.asPath) + + ant.scp( + file: new File(buildDir, "libs/samples-all.jar"), + todir: brick_user + '@' + brick_host + ':' + brick_home, + username: brick_user, + password: '', + trust: true + ) + } +} diff --git a/samples/src/main/java/Main.java b/samples/src/main/java/com/github/bdeneuter/mindstorms/samples/HelloWorld.java similarity index 63% rename from samples/src/main/java/Main.java rename to samples/src/main/java/com/github/bdeneuter/mindstorms/samples/HelloWorld.java index f8bc8eb..a0f952b 100644 --- a/samples/src/main/java/Main.java +++ b/samples/src/main/java/com/github/bdeneuter/mindstorms/samples/HelloWorld.java @@ -1,13 +1,18 @@ +package com.github.bdeneuter.mindstorms.samples; + +import com.google.common.base.Joiner; import lejos.hardware.Battery; import lejos.hardware.Sound; import lejos.utility.Delay; -public class Main { +import java.util.Arrays; + +public class HelloWorld { public static void main(String[] args) { String message = args.length > 0 ? args[0] : "Hello world!"; - System.out.println(message); + System.out.println(Joiner.on(", ").join(Arrays.asList("Hello", "world", "with", "guava"))); Delay.msDelay(500); Sound.beep(); diff --git a/settings.gradle b/settings.gradle index f4df05b..6c5aa9c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,2 @@ rootProject.name = 'mindstorms' -//include ':dbusjava' -include ':ev3classes' include ':samples'