65 private static int k_maxSpeed = 10000;
67 private class Processor {
69 private int m_nextMotor = 0;
74 private int m_maxMotors = 0;
82 if (
Device.m_boardVersion == 4) {
85 if ((motor !=
null) && motor.m_changed) {
87 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setMotor, (
byte) motor.m_motorNo, (
short) motor.m_currentValue);
88 motor.m_changed =
false;
95 if ((motor !=
null) && motor.m_changed) {
96 if (Math.abs(motor.m_currentValue) < 32000) {
101 if (Device.m_boardSubVersion == 0) {
102 throw new TwoWire.HardwareException(
"Operation not supported by hardware: update firmware");
104 m_device.sendCommand(m_i2cAddr, TwoWire.k_setMotor32, (
byte) motor.m_motorNo, motor.m_currentValue);
110 byte[] data =
new byte[(3 * count) + 1];
111 ByteBuffer buffer = ByteBuffer.wrap(data, 0, data.length);
112 buffer.order(ByteOrder.LITTLE_ENDIAN);
114 buffer.put((
byte) count);
116 if ((motor !=
null) && motor.m_changed) {
118 buffer.put((
byte) motor.m_motorNo);
119 buffer.putShort((
short) motor.m_currentValue);
121 motor.m_changed =
false;
127 m_device.sendCommand(m_addr, TwoWire.k_setMultipleMotors, data);
132 private int getMaxMotors() {
133 if (m_maxMotors == 0) {
134 m_maxMotors = m_device.getByte(m_addr, TwoWire.k_getMaxMotors);
139 return (m_maxMotors);
142 private void verifyPin(
int pin,
boolean pwm) {
154 if (!m_device.isPinValid(m_addr, pin, pwm ? Device.PinType.PWMPin : Device.PinType.OutputPin)) {
155 throw new TwoWire.HardwareException(
156 String.format(
"SmartMotor: Invalid %s pin: %d", pwm ?
"PWM" :
"DIR", pin));
162 if (m_device.checkUsedPin(m_addr, pin)) {
163 throw new TwoWire.HardwareException(String.format(
"SmartMotor: Pin %d is in use", pin));
168 static ArrayList<Processor> m_processors =
new ArrayList<Processor>();
170 static void periodic() {
171 for (Processor processor : m_processors) {
172 processor.periodic();
176 Processor getProcessor(
int addr) {
179 for (
int i = 0; i < m_processors.size(); i++) {
180 processor = m_processors.get(i);
182 if (processor.m_addr == addr) {
187 processor =
new Processor(addr);
188 m_processors.add(processor);
193 private Processor m_processor;
194 private Device m_device =
null;
198 private int m_motorNo;
199 private int m_currentValue;
200 private int m_i2cAddr = 0;
201 private double m_maxSpeed = 0;
202 private boolean m_changed =
false;
204 private Encoder m_encoder =
null;
206 private void init(
SmartMotorType type,
int pwmPin,
int dirPin,
int min,
int zero,
int max,
int i2cAddr) {
209 initTW(type, pwmPin, dirPin, min, zero, max, i2cAddr);
217 private void initTW(
SmartMotorType type,
int pwmPin,
int dirPin,
int min,
int zero,
int max,
int i2cAddr) {
218 if (pwmPin == dirPin) {
219 throw new TwoWire.HardwareException(String.format(
"SmartMotor: The pwmPin and dirPin must be different"));
222 m_device = Device.getInstance();
223 m_processor = getProcessor(i2cAddr);
224 int maxMotors = m_processor.getMaxMotors();
228 m_processor.verifyPin(pwmPin,
true);
230 m_processor.verifyPin(dirPin,
false);
234 || (m_processor.m_nextMotor >= maxMotors)) {
235 throw new TwoWire.HardwareException(
"Invalid motor param");
238 if (m_processor.m_motors ==
null) {
239 m_processor.m_motors =
new SmartMotor[maxMotors];
243 m_motorNo = m_processor.m_nextMotor++;
244 m_processor.m_motors[m_motorNo] =
this;
247 m_device.setUsedPin(m_i2cAddr, pwmPin);
250 m_device.setUsedPin(m_i2cAddr, dirPin);
256 m_device.sendCommand(m_i2cAddr, TwoWire.k_configureMotor, (
byte) m_motorNo,
280 init(type, pwmPin, dirPin, 1000, 1500, 2000,
Device.k_mainTwoWireId);
300 init(type, pwmPin, dirPin, 1000, 1500, 2000, i2cAddr);
325 public SmartMotor(
int pin,
int min,
int zero,
int max,
int i2cAddr) {
336 m_maxSpeed = maxSpeed;
349 public void set(
double value) {
356 }
else if (value < -1.0) {
360 send = (int) (value * 1000);
364 if (m_encoder ==
null) {
367 if (m_maxSpeed != 0) {
371 send = (int) ((value > k_maxSpeed) ? k_maxSpeed * Math.signum(value) : value);
375 if (m_encoder ==
null) {
379 value =
Gyro.
normalize(value + m_encoder.getZero(), m_encoder.getRange());
382 value += m_encoder.getZero();
384 send = (int) (value * 10);
388 Logger.
log(
"SmartMotor", 3,
"Invalid motor type: " + m_mode);
392 if (send != m_currentValue) {
394 m_currentValue = send;
408 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setFeedbackDevice, (
byte) m_motorNo, (
byte) encoder.getEncoderNo());
424 if (mode != m_mode) {
426 m_currentValue = 10000;
429 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setMotorMode, (
byte) m_motorNo, (
byte) m_mode.ordinal());
442 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDFTerm, (
byte) m_motorNo, (
float) f);
454 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDITerm, (
byte) m_motorNo, (
float) i);
466 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDPTerm, (
byte) m_motorNo, (
float) p);
475 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDIZone, (
byte) m_motorNo, (
float) z);
483 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setMotorInverted, (
byte) m_motorNo, (
byte) (invert ? 1 : 0));
491 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDDTerm, (
byte) m_motorNo, (
float) d);
509 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDMinPower, (
byte) m_motorNo, (
float) minPower);
519 m_device.sendCommand(m_i2cAddr,
TwoWire.k_setPIDDeadZone, (
byte) m_motorNo, (
float) deadZone);