/*
* Catroid: An on-device visual programming system for Android devices
* Copyright (C) 2010-2016 The Catrobat Team
* (<http://developer.catrobat.org/credits>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* An additional term exception under section 7 of the GNU Affero
* General Public License, version 3, is available at
* http://developer.catrobat.org/license_additional_term
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.catrobat.catroid.devices.mindstorms.nxt.sensors;
import android.util.Log;
import org.catrobat.catroid.devices.mindstorms.MindstormsConnection;
import org.catrobat.catroid.devices.mindstorms.MindstormsException;
import org.catrobat.catroid.devices.mindstorms.MindstormsSensor;
import org.catrobat.catroid.devices.mindstorms.nxt.Command;
import org.catrobat.catroid.devices.mindstorms.nxt.CommandByte;
import org.catrobat.catroid.devices.mindstorms.nxt.CommandType;
import org.catrobat.catroid.devices.mindstorms.nxt.NXTError;
import org.catrobat.catroid.devices.mindstorms.nxt.NXTReply;
import java.util.Locale;
public abstract class NXTSensor implements MindstormsSensor {
public enum Sensor {
NO_SENSOR,
TOUCH,
SOUND,
LIGHT_INACTIVE,
LIGHT_ACTIVE,
ULTRASONIC;
public static String[] getSensorCodes() {
String[] valueStrings = new String[values().length];
for (int i = 0; i < values().length; ++i) {
valueStrings[i] = values()[i].name();
}
return valueStrings;
}
public String getSensorCode() {
return getSensorCode(this);
}
public static String getSensorCode(NXTSensor.Sensor sensor) {
return sensor.name();
}
public static NXTSensor.Sensor getSensorFromSensorCode(String sensorCode) {
if (sensorCode == null) {
return Sensor.NO_SENSOR;
}
try {
return valueOf(sensorCode);
} catch (IllegalArgumentException e) {
return Sensor.NO_SENSOR;
}
}
}
protected final int port;
protected final NXTSensorType sensorType;
protected final NXTSensorMode sensorMode;
protected final int updateInterval = 250;
protected final MindstormsConnection connection;
protected boolean hasInit;
protected int lastValidValue = 0;
public static final String TAG = NXTSensor.class.getSimpleName();
public NXTSensor(int port, NXTSensorType sensorType, NXTSensorMode sensorMode, MindstormsConnection connection) {
this.port = port;
this.sensorType = sensorType;
this.sensorMode = sensorMode;
this.connection = connection;
}
protected void updateTypeAndMode() {
Command command = new Command(CommandType.DIRECT_COMMAND, CommandByte.SET_INPUT_MODE, true);
command.append((byte) port);
command.append(sensorType.getByte());
command.append(sensorMode.getByte());
NXTReply reply = new NXTReply(connection.sendAndReceive(command));
NXTError.checkForError(reply, 3);
}
protected int getScaledValue() {
return getSensorReadings().scaled;
}
protected int getRawValue() {
return getSensorReadings().raw;
}
protected int getNormalizedValue() {
return getSensorReadings().normalized;
}
public SensorReadings getSensorReadings() {
if (!hasInit) {
initialize();
}
SensorReadings sensorReadings = new SensorReadings();
Command command = new Command(CommandType.DIRECT_COMMAND, CommandByte.GET_INPUT_VALUES, true);
command.append((byte) port);
NXTReply reply = new NXTReply(connection.sendAndReceive(command));
NXTError.checkForError(reply, 16);
sensorReadings.raw = reply.getShort(8);
sensorReadings.normalized = reply.getShort(10);
sensorReadings.scaled = reply.getShort(12);
return sensorReadings;
}
protected void initialize() {
if (connection != null && connection.isConnected()) {
updateTypeAndMode();
try {
Thread.sleep(100);
resetScaledValue();
Thread.sleep(100);
updateTypeAndMode();
hasInit = true;
} catch (InterruptedException e) {
hasInit = false;
}
} else {
hasInit = false;
}
}
protected void resetScaledValue() {
Command command = new Command(CommandType.DIRECT_COMMAND, CommandByte.RESET_INPUT_SCALED_VALUE, false);
command.append((byte) port);
connection.send(command);
}
private static class SensorReadings {
public int raw;
public int normalized;
public int scaled;
}
@Override
public int getUpdateInterval() {
return updateInterval;
}
@Override
public void updateLastSensorValue() {
try {
lastValidValue = getValue();
} catch (MindstormsException e) {
Log.e(TAG, e.getMessage());
}
}
@Override
public int getLastSensorValue() {
return lastValidValue;
}
@Override
public String getName() {
return String.format(Locale.getDefault(), "%s_%s_%d", TAG, sensorType.name(), port);
}
@Override
public int getConnectedPort() {
return port;
}
}