mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
Merge branch 'main' into 2027
This commit is contained in:
@@ -6,8 +6,10 @@ package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.units.Measure;
|
||||
import edu.wpi.first.units.Unit;
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.Collection;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/** A backend is a generic interface for Epilogue to log discrete data points. */
|
||||
public interface EpilogueBackend {
|
||||
@@ -193,6 +195,17 @@ public interface EpilogueBackend {
|
||||
log(identifier, array, struct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a protobuf-serializable object.
|
||||
*
|
||||
* @param identifier the identifier of the data point
|
||||
* @param value the value of the data point
|
||||
* @param proto the protobuf to use to serialize the data
|
||||
* @param <P> the protobuf-serializable type
|
||||
* @param <M> the protobuf message type
|
||||
*/
|
||||
<P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto);
|
||||
|
||||
/**
|
||||
* Logs a measurement's value in terms of its base unit.
|
||||
*
|
||||
|
||||
@@ -16,17 +16,20 @@ import edu.wpi.first.datalog.FloatArrayLogEntry;
|
||||
import edu.wpi.first.datalog.FloatLogEntry;
|
||||
import edu.wpi.first.datalog.IntegerArrayLogEntry;
|
||||
import edu.wpi.first.datalog.IntegerLogEntry;
|
||||
import edu.wpi.first.datalog.ProtobufLogEntry;
|
||||
import edu.wpi.first.datalog.RawLogEntry;
|
||||
import edu.wpi.first.datalog.StringArrayLogEntry;
|
||||
import edu.wpi.first.datalog.StringLogEntry;
|
||||
import edu.wpi.first.datalog.StructArrayLogEntry;
|
||||
import edu.wpi.first.datalog.StructLogEntry;
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/** A backend implementation that saves information to a WPILib {@link DataLog} file on disk. */
|
||||
public class FileBackend implements EpilogueBackend {
|
||||
@@ -34,6 +37,7 @@ public class FileBackend implements EpilogueBackend {
|
||||
private final Map<String, DataLogEntry> m_entries = new HashMap<>();
|
||||
private final Map<String, NestedBackend> m_subLoggers = new HashMap<>();
|
||||
private final Set<Struct<?>> m_seenSchemas = new HashSet<>();
|
||||
private final Set<Protobuf<?, ?>> m_seenProtos = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Creates a new file-based backend.
|
||||
@@ -166,4 +170,19 @@ public class FileBackend implements EpilogueBackend {
|
||||
|
||||
((StructArrayLogEntry<S>) m_entries.get(identifier)).append(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
|
||||
// DataLog.addSchema has checks that we're able to skip, avoiding allocations
|
||||
if (m_seenProtos.add(proto)) {
|
||||
m_dataLog.addSchema(proto);
|
||||
}
|
||||
|
||||
if (!m_entries.containsKey(identifier)) {
|
||||
m_entries.put(identifier, ProtobufLogEntry.create(m_dataLog, identifier, proto));
|
||||
}
|
||||
|
||||
((ProtobufLogEntry<P>) m_entries.get(identifier)).append(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/**
|
||||
* A backend implementation that only logs data when it changes. Useful for keeping bandwidth and
|
||||
@@ -243,4 +245,17 @@ public class LazyBackend implements EpilogueBackend {
|
||||
m_previousValues.put(identifier, value.clone());
|
||||
m_backend.log(identifier, value, struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
|
||||
var previous = m_previousValues.get(identifier);
|
||||
|
||||
if (Objects.equals(previous, value)) {
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
|
||||
m_previousValues.put(identifier, value);
|
||||
m_backend.log(identifier, value, proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/**
|
||||
* A backend implementation that delegates to other backends. Helpful for simultaneous logging to
|
||||
@@ -137,4 +139,11 @@ public class MultiBackend implements EpilogueBackend {
|
||||
backend.log(identifier, value, struct);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
|
||||
for (EpilogueBackend backend : m_backends) {
|
||||
backend.log(identifier, value, proto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,21 @@ import edu.wpi.first.networktables.FloatPublisher;
|
||||
import edu.wpi.first.networktables.IntegerArrayPublisher;
|
||||
import edu.wpi.first.networktables.IntegerPublisher;
|
||||
import edu.wpi.first.networktables.NetworkTableInstance;
|
||||
import edu.wpi.first.networktables.ProtobufPublisher;
|
||||
import edu.wpi.first.networktables.Publisher;
|
||||
import edu.wpi.first.networktables.RawPublisher;
|
||||
import edu.wpi.first.networktables.StringArrayPublisher;
|
||||
import edu.wpi.first.networktables.StringPublisher;
|
||||
import edu.wpi.first.networktables.StructArrayPublisher;
|
||||
import edu.wpi.first.networktables.StructPublisher;
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/**
|
||||
* A backend implementation that sends data over network tables. Be careful when using this, since
|
||||
@@ -36,6 +39,7 @@ public class NTEpilogueBackend implements EpilogueBackend {
|
||||
private final Map<String, Publisher> m_publishers = new HashMap<>();
|
||||
private final Map<String, NestedBackend> m_nestedBackends = new HashMap<>();
|
||||
private final Set<Struct<?>> m_seenSchemas = new HashSet<>();
|
||||
private final Set<Protobuf<?, ?>> m_seenProtos = new HashSet<>();
|
||||
private final Function<String, IntegerPublisher> m_createIntPublisher;
|
||||
private final Function<String, FloatPublisher> m_createFloatPublisher;
|
||||
private final Function<String, DoublePublisher> m_createDoublePublisher;
|
||||
@@ -198,4 +202,21 @@ public class NTEpilogueBackend implements EpilogueBackend {
|
||||
publisher.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
|
||||
// NetworkTableInstance.addSchema has checks that we're able to skip, avoiding allocations
|
||||
if (m_seenProtos.add(proto)) {
|
||||
m_nt.addSchema(proto);
|
||||
}
|
||||
|
||||
if (m_publishers.containsKey(identifier)) {
|
||||
((ProtobufPublisher<P>) m_publishers.get(identifier)).set(value);
|
||||
} else {
|
||||
ProtobufPublisher<P> publisher = m_nt.getProtobufTopic(identifier, proto).publish();
|
||||
m_publishers.put(identifier, publisher);
|
||||
publisher.set(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/**
|
||||
* A backend that logs to an underlying backend, prepending all logged data with a specific prefix.
|
||||
@@ -147,4 +149,9 @@ public class NestedBackend implements EpilogueBackend {
|
||||
public <S> void log(String identifier, S[] value, Struct<S> struct) {
|
||||
m_impl.log(withPrefix(identifier), value, struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P, M extends ProtoMessage<M>> void log(String identifier, P value, Protobuf<P, M> proto) {
|
||||
m_impl.log(m_prefix + identifier, value, proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
package edu.wpi.first.epilogue.logging;
|
||||
|
||||
import edu.wpi.first.util.protobuf.Protobuf;
|
||||
import edu.wpi.first.util.struct.Struct;
|
||||
import us.hebi.quickbuf.ProtoMessage;
|
||||
|
||||
/** Null backend implementation that logs nothing. */
|
||||
public class NullBackend implements EpilogueBackend {
|
||||
@@ -62,4 +64,8 @@ public class NullBackend implements EpilogueBackend {
|
||||
|
||||
@Override
|
||||
public <S> void log(String identifier, S[] value, Struct<S> struct) {}
|
||||
|
||||
@Override
|
||||
public <P, M extends ProtoMessage<M>> void log(
|
||||
String identifier, P value, Protobuf<P, M> proto) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user