/**
* Copyright 2012 Kevin J. Jones (http://www.kevinjjones.co.uk)
*
* Licensed 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.
*/
package uk.co.kevinjjones.vehicle;
import uk.co.kevinjjones.Log;
import uk.co.kevinjjones.model.*;
/**
* Speed virtual stream.
*/
public class SpeedStream extends StreamBase {
public static String NAME = "Speed";
private View _view;
private ROStream _lusp;
private ROStream _rusp;
private ROStream _ldsp;
private ROStream _rdsp;
private ROStream _lowt;
public SpeedStream() {
}
@Override
public void setView(View view, Object arg, ParamHandler handler, WithError<Boolean, BasicError> ok) {
super.setView(view, arg, handler, ok);
_view = view;
_lusp = _view.getStream(WheelStream.name(WheelStream.LUSP));
_rusp = _view.getStream(WheelStream.name(WheelStream.RUSP));
_ldsp = _view.getStream(WheelStream.name(WheelStream.LDSP));
_rdsp = _view.getStream(WheelStream.name(WheelStream.RDSP));
_lowt = _view.getStream(LowThrottleStream.NAME);
if (_lusp != null && _rusp != null && _ldsp != null && _rdsp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using four wheel speeds to calculate speed"));
} else if (_lusp != null && _rusp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using two undriven wheel sensors to calculate speed"));
} else if (_lusp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using left undriven wheel sensors to calculate speed"));
} else if (_rusp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using right undriven wheel sensors to calculate speed"));
} else if (_ldsp != null && _rdsp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using two driven wheel sensors to calculate speed"));
} else if (_ldsp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using left driven wheel sensors to calculate speed"));
} else if (_rdsp != null) {
ok.addError(new BasicError(BasicError.WARN, "Using right driven wheel sensors to calculate speed"));
} else {
ok.addError(new BasicError(BasicError.WARN, "No wheel speeds available"));
ok.setValue(false);
}
}
@Override
public String name() {
return NAME;
}
@Override
public String description() {
return "Speed";
}
@Override
public String axis() {
return "Speed";
}
@Override
public String units() {
switch (isKPH(false)) {
case 1:
return "kph";
case 2:
return "mph";
}
return null;
}
@Override
public int size() {
return _view.getStream(Log.TIME_STREAM).size();
}
private double safeAverage(double v1, double v2) {
if (v1 != 0 && v2 != 0) {
return (v1+v2)/2;
} else if (v1 != 0) {
return v1;
} else {
return v2;
}
}
@Override
public double getNumeric(int position) throws NumberFormatException {
if (_lusp != null && _rusp != null && _ldsp != null && _rdsp != null) {
// With four wheel sensors we track undriven under accel
// and driven under braking by looking at tps
// at tps
double avgDriven = safeAverage(_ldsp.getNumeric(position), _rdsp.getNumeric(position));
double avgUndriven = safeAverage(_lusp.getNumeric(position), _rusp.getNumeric(position));
if (_lowt != null && _lowt.getNumeric(position) == 1) {
return avgDriven;
} else {
return avgUndriven;
}
} else if (_lusp != null && _rusp != null) {
// With only 2 undriven go for max to remove lock ups
return Math.max(_lusp.getNumeric(position), _rusp.getNumeric(position));
} else if (_lusp != null) {
return _lusp.getNumeric(position);
} else if (_rusp != null) {
return _rusp.getNumeric(position);
} else if (_ldsp != null && _rdsp != null) {
// With only 2 undriven go for min to remove spin
return Math.min(_ldsp.getNumeric(position), _rdsp.getNumeric(position));
} else if (_ldsp != null) {
return _ldsp.getNumeric(position);
} else if (_rdsp != null) {
return _rdsp.getNumeric(position);
}
return 0;
}
}