Skip to content

sync local changes to get as5048 data flowing to a motor. #1439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions src/main/java/org/myrobotlab/sensor/EncoderData.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.myrobotlab.sensor;

import java.util.Objects;

public class EncoderData {

/**
Expand Down Expand Up @@ -39,6 +41,55 @@ public class EncoderData {
* mapped value of input
*/
public double mappedValue;

public String getPin() {
return pin;
}

public void setPin(String pin) {
this.pin = pin;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public Double getAngle() {
return angle;
}

public void setAngle(Double angle) {
this.angle = angle;
}

public double getValue() {
return value;
}

public void setValue(double value) {
this.value = value;
}

public long getTimestamp() {
return timestamp;
}

public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}


public EncoderData(String source, String pin, double value, Double angle) {
this.timestamp = System.currentTimeMillis();
Expand All @@ -61,4 +112,23 @@ public String toString() {
return sb.toString();
}

@Override
public int hashCode() {
return Objects.hash(angle, mappedValue, pin, source, timestamp, type, value);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EncoderData other = (EncoderData) obj;
return Objects.equals(angle, other.angle) && Double.doubleToLongBits(mappedValue) == Double.doubleToLongBits(other.mappedValue) && Objects.equals(pin, other.pin)
&& Objects.equals(source, other.source) && timestamp == other.timestamp && Objects.equals(type, other.type)
&& Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value);
}

}
28 changes: 25 additions & 3 deletions src/main/java/org/myrobotlab/sensor/EncoderListener.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
package org.myrobotlab.sensor;

import org.myrobotlab.framework.interfaces.Attachable;
/**
* Any device/service that wants to handle the onEncoderData method
* and encoder publisher will publish the encoder data to listeners.
*/
public interface EncoderListener {

public String getName();

public interface EncoderListener extends Attachable {
public void onEncoderData(EncoderData encoderData);

default public void attachEncoderPublisher(EncoderPublisher publisher) {
attachEncoderPublisher(publisher.getName());
}

void onEncoderData(EncoderData data);
default public void attachEncoderPublisher(String name) {
send(name, "attachEncoderListener", getName());
}

default public void detachEncoderPublisher(EncoderPublisher publisher) {
detachEncoderPublisher(publisher.getName());
}

default public void detachEncoderPublisher(String name) {
send(name, "detachEncoderListener", getName());
}

public void send(String name, String method, Object... data);

}
48 changes: 46 additions & 2 deletions src/main/java/org/myrobotlab/sensor/EncoderPublisher.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
package org.myrobotlab.sensor;

public interface EncoderPublisher {
public EncoderData publishEncoderData(EncoderData Data);
import org.myrobotlab.framework.interfaces.NameProvider;

/**
* The EncoderPublisher interface is used with any device that publishes encoder data
* such as the AS5048A and the AMT203 encoders. Analog pins (potentiometers) can also
* emulate and publish encoder data.
*/
public interface EncoderPublisher extends NameProvider {

// These are all the methods that the Encoder publisher should produce.
public static String[] publishMethods = new String[] { "publishEncoderData" };

// Define the methods that an Encoder publisher should have for publishing data.
default public EncoderData publishEncoderData(EncoderData data) {
return data;
};

// helper default methods to attach and detach a listener.
default public void attachEncoderListener(String name) {
for (String publishMethod : EncoderPublisher.publishMethods) {
addListener(publishMethod, name);
}
}

default public void attachEncoderListener(EncoderListener listener) {
for (String publishMethod : EncoderPublisher.publishMethods) {
addListener(publishMethod, listener.getName());
}
}

// detach methods
default public void detachEncoderListener(String name) {
for (String publishMethod : EncoderPublisher.publishMethods) {
removeListener(publishMethod, name);
}
}

default public void detachEncoderListener(EncoderListener listener) {
detachEncoderListener(listener.getName());
}

// Add the addListener method to the interface all services implement this.
public void addListener(String topicMethod, String callbackName);

public void removeListener(String topicMethod, String callbackName);

}
8 changes: 8 additions & 0 deletions src/main/java/org/myrobotlab/sensor/TimeEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,12 @@ public void stopMove() {
public void attachEncoderController(EncoderController controller) {
// NoOp, the TimeEncoder doesn't need a controller.
}

@Override
public void updateEncoderData(EncoderData data) {
// NoOp, this encoder updates itself.
// TODO: should we publish an invoke here?
// invoke("publishEncoderData", data);

}
}
30 changes: 29 additions & 1 deletion src/main/java/org/myrobotlab/service/Amt203Encoder.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.myrobotlab.service;

import org.myrobotlab.logging.LoggingFactory;
import org.myrobotlab.sensor.EncoderData;
import org.myrobotlab.sensor.EncoderPublisher;
import org.myrobotlab.service.abstracts.AbstractPinEncoder;
import org.myrobotlab.service.config.Amt203EncoderConfig;
import org.myrobotlab.service.config.ServiceConfig;
import org.myrobotlab.service.interfaces.EncoderControl;

Expand All @@ -23,7 +26,7 @@
* @author kwatters
*
*/
public class Amt203Encoder extends AbstractPinEncoder<ServiceConfig> implements EncoderControl {
public class Amt203Encoder extends AbstractPinEncoder<Amt203EncoderConfig> implements EncoderControl, EncoderPublisher {

private static final long serialVersionUID = 1L;

Expand All @@ -50,4 +53,29 @@ public static void main(String[] args) throws Exception {
log.info("Here we are..");
}

@Override
public void updateEncoderData(EncoderData data) {
// publish the updated encoder data (this is updated from the arduino..)
invoke("publishEncoderData", data);
}

@Override
public Amt203EncoderConfig apply(Amt203EncoderConfig c) {
super.apply(c);
this.setPin(c.pin);
// TODO: how we apply the config of the controller?
// String controllerName = c.controller;
// this.controller= null;
// TODO: should we have a handle to our controller?
//this.controller = c.controller;
if (c.controller != null) {
try {
attach(c.controller);
} catch (Exception e) {
error(e);
}
}
return c;
}

}
34 changes: 28 additions & 6 deletions src/main/java/org/myrobotlab/service/Arduino.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,24 @@ public void reattach(DeviceMapping dm) {
if (servo.isEnabled()) {
msg.servoAttachPin(dm.getId(), pin);
}
} else if (attachable instanceof As5048AEncoder) {
// reattach it!
As5048AEncoder enc = (As5048AEncoder)attachable;
log.info("================ re-attaching {} {} {} ================", enc.getName(), dm.getId(), enc.getPin());
msg.encoderAttach(dm.getId(), 1, Integer.valueOf(enc.getPin()));
} else if (attachable instanceof Amt203Encoder) {
// reattach it!
Amt203Encoder enc = (Amt203Encoder)attachable;
log.info("================ re-attaching {} {} {} ================", enc.getName(), dm.getId(), enc.getPin());
msg.encoderAttach(dm.getId(), 0, Integer.valueOf(enc.getPin()));
} else if (attachable instanceof MotorDualPwm) {
// reattach it!
MotorDualPwm motor = (MotorDualPwm)attachable;
int[] pins = new int[] {Integer.valueOf(motor.getLeftPwmPin()), Integer.valueOf(motor.getRightPwmPin())};
// TODO: what's the type?!
int type = 0;
log.info("================ re-attaching {} {} {} ================", motor.getName(), dm.getId(), pins);
msg.motorAttach(dm.getId(),type, pins );
} else if (attachable instanceof UltrasonicSensorControl) {
log.warn("UltrasonicSensorControl not implemented");
// reattach logic
Expand All @@ -511,15 +529,13 @@ public void reattach(DeviceMapping dm) {
} else if (attachable instanceof PinListener) {
PinListener pl = (PinListener) attachable;
attachPinListener(pl);

// on reattach get back to its previous state enabled/disabled
if (attachable instanceof Pir) {
Pir pir = (Pir) attachable;
if (pir.isEnabled()) {
pir.enable();
}
}

} else if (attachable instanceof I2CControl) {
error("I2CControl sync not implemented");
} else {
Expand Down Expand Up @@ -1685,25 +1701,31 @@ public EncoderData publishEncoderData(EncoderData data) {
@Override
public EncoderData publishEncoderData(Integer deviceId, Integer position) {
// Also need to log this

EncoderControl ec = (EncoderControl) getDevice(deviceId);
String pin = null;
Double angle = null;
if (ec instanceof Amt203Encoder) {
// type = 0;
pin = ((Amt203Encoder) ec).getPin();
// TODO: test this is this correct? is the resolution correct?
angle = 360.0 * position / ((Amt203Encoder) ec).resolution;
} else if (ec instanceof As5048AEncoder) {
// type = 1;
pin = ((As5048AEncoder) ec).getPin();
angle = 360.0 * position / ((As5048AEncoder) ec).resolution;
log.info("Angle : {}", angle);
// log.info("Angle : {}", angle);
} else {
error("unknown encoder type {}", ec.getClass().getName());
}

// TODO: figure out how to handle analog pin data as encoder data..
EncoderData data = new EncoderData(ec.getName(), pin, position, angle);
// log.info("Publish Encoder Data Raw {}", data);

// TODO: how do i publish the data from the encoder?
// ec.publishEncoderData(data);
// This will pass the encoder data to the encoder and the encoder will publish it to listeners.
//log.info("Encoder data! {}", data);
((EncoderControl)ec).updateEncoderData(data);
// invoke("publishEncoderData", data);
// TODO: all this code needs to move out of here!
return data;
}
Expand Down
Loading