mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-27 02:01:40 +00:00
Assert that version checking won't throw on startup (#1512)
# Overview Previously if the coproc came up later, getProperty would return the string literal "null", which made us print the BFW. Add tests to make sure that we don't do that anymore by rebooting a sim coproc + robot in a combination of different orders.
This commit is contained in:
@@ -80,7 +80,8 @@ public class NTTopicSet {
|
||||
.publish(
|
||||
PhotonPipelineResult.photonStruct.getTypeString(),
|
||||
PubSubOption.periodic(0.01),
|
||||
PubSubOption.sendAll(true));
|
||||
PubSubOption.sendAll(true),
|
||||
PubSubOption.keepDuplicates(true));
|
||||
|
||||
resultPublisher =
|
||||
new PacketPublisher<PhotonPipelineResult>(rawBytesEntry, PhotonPipelineResult.photonStruct);
|
||||
|
||||
@@ -90,6 +90,13 @@ public class PacketSubscriber<T> implements AutoCloseable {
|
||||
public String getInterfaceUUID() {
|
||||
// ntcore hands us a JSON string with leading/trailing quotes - remove those
|
||||
var uuidStr = subscriber.getTopic().getProperty("message_uuid");
|
||||
|
||||
// "null" can be returned if the property does not exist. From system knowledge, uuid can never
|
||||
// be the string literal "null".
|
||||
if (uuidStr.equals("null")) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return uuidStr.replace("\"", "");
|
||||
}
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ public class TimeSyncClient {
|
||||
public long pingsSent;
|
||||
// incoming count
|
||||
public long pongsReceived;
|
||||
// when we last heard back from the server
|
||||
// when we last heard back from the server, uS, in local time base
|
||||
public long lastPongTime;
|
||||
// RTT2, time from ping send to pong recieve at the client
|
||||
// RTT2, time from ping send to pong receive at the client, uS
|
||||
public long rtt2;
|
||||
|
||||
public PingMetadata(
|
||||
@@ -87,10 +87,8 @@ public class TimeSyncClient {
|
||||
this.port = port;
|
||||
this.interval = interval;
|
||||
|
||||
synchronized (mutex) {
|
||||
this.handle = TimeSyncClient.create(server, port, interval);
|
||||
TimeSyncClient.start(handle);
|
||||
}
|
||||
this.handle = TimeSyncClient.create(server, port, interval);
|
||||
TimeSyncClient.start(handle);
|
||||
}
|
||||
|
||||
public void setServer(String newServer) {
|
||||
@@ -121,7 +119,12 @@ public class TimeSyncClient {
|
||||
*/
|
||||
public long getOffset() {
|
||||
synchronized (mutex) {
|
||||
return TimeSyncClient.getOffset(handle);
|
||||
if (handle > 0) {
|
||||
return TimeSyncClient.getOffset(handle);
|
||||
}
|
||||
|
||||
System.err.println("TimeSyncClient: use after free?");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +139,12 @@ public class TimeSyncClient {
|
||||
|
||||
public PingMetadata getPingMetadata() {
|
||||
synchronized (mutex) {
|
||||
return TimeSyncClient.getLatestMetadata(handle);
|
||||
if (handle > 0) {
|
||||
return TimeSyncClient.getLatestMetadata(handle);
|
||||
}
|
||||
|
||||
System.err.println("TimeSyncClient: use after free?");
|
||||
return new PingMetadata(0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package org.photonvision.jni;
|
||||
|
||||
public class TimeSyncServer {
|
||||
private final Object mutex = new Object();
|
||||
private long handle;
|
||||
|
||||
public TimeSyncServer(int port) {
|
||||
@@ -25,7 +26,13 @@ public class TimeSyncServer {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
TimeSyncServer.start(handle);
|
||||
synchronized (mutex) {
|
||||
if (handle > 0) {
|
||||
TimeSyncServer.start(handle);
|
||||
} else {
|
||||
System.err.println("TimeSyncServer: use after free?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class PhotonPipelineMetadata implements PhotonStructSerializable<PhotonPi
|
||||
// Mirror of the heartbeat entry -- monotonically increasing
|
||||
public long sequenceID;
|
||||
|
||||
// Time from last Time Sync Pong received and the construction of this metadata
|
||||
// Time from last Time Sync Pong received and the construction of this metadata, in uS
|
||||
public long timeSinceLastPong;
|
||||
|
||||
public PhotonPipelineMetadata(
|
||||
@@ -73,12 +73,14 @@ public class PhotonPipelineMetadata implements PhotonStructSerializable<PhotonPi
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PhotonPipelineMetadata [sequenceID="
|
||||
+ sequenceID
|
||||
+ ", captureTimestampMicros="
|
||||
return "PhotonPipelineMetadata [captureTimestampMicros="
|
||||
+ captureTimestampMicros
|
||||
+ ", publishTimestampMicros="
|
||||
+ publishTimestampMicros
|
||||
+ ", sequenceID="
|
||||
+ sequenceID
|
||||
+ ", timeSinceLastPong="
|
||||
+ timeSinceLastPong
|
||||
+ "]";
|
||||
}
|
||||
|
||||
@@ -86,9 +88,10 @@ public class PhotonPipelineMetadata implements PhotonStructSerializable<PhotonPi
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (int) (sequenceID ^ (sequenceID >>> 32));
|
||||
result = prime * result + (int) (captureTimestampMicros ^ (captureTimestampMicros >>> 32));
|
||||
result = prime * result + (int) (publishTimestampMicros ^ (publishTimestampMicros >>> 32));
|
||||
result = prime * result + (int) (sequenceID ^ (sequenceID >>> 32));
|
||||
result = prime * result + (int) (timeSinceLastPong ^ (timeSinceLastPong >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -98,9 +101,10 @@ public class PhotonPipelineMetadata implements PhotonStructSerializable<PhotonPi
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
PhotonPipelineMetadata other = (PhotonPipelineMetadata) obj;
|
||||
if (sequenceID != other.sequenceID) return false;
|
||||
if (captureTimestampMicros != other.captureTimestampMicros) return false;
|
||||
if (publishTimestampMicros != other.publishTimestampMicros) return false;
|
||||
if (sequenceID != other.sequenceID) return false;
|
||||
if (timeSinceLastPong != other.timeSinceLastPong) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,5 +69,6 @@ public class PhotonPipelineResultProto
|
||||
msg.setSequenceId(value.metadata.getSequenceID());
|
||||
msg.setCaptureTimestampMicros(value.metadata.getCaptureTimestampMicros());
|
||||
msg.setNtPublishTimestampMicros(value.metadata.getPublishTimestampMicros());
|
||||
msg.setTimeSinceLastPongMicros(value.metadata.timeSinceLastPong);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,17 @@
|
||||
|
||||
using namespace wpi::tsp;
|
||||
|
||||
#define CHECK_PTR(ptr) \
|
||||
if (!ptr) { \
|
||||
fmt::println("Got invalid pointer?? {}:{}", __FILE__, __LINE__); \
|
||||
return; \
|
||||
}
|
||||
#define CHECK_PTR_RETURN(ptr, default) \
|
||||
if (!ptr) { \
|
||||
fmt::println("Got invalid pointer?? {}:{}", __FILE__, __LINE__); \
|
||||
return default; \
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a class and keeps it as a global reference.
|
||||
*
|
||||
@@ -117,6 +128,7 @@ JNIEXPORT void JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncClient_start
|
||||
(JNIEnv*, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR(ptr);
|
||||
TimeSyncClient* client = reinterpret_cast<TimeSyncClient*>(ptr);
|
||||
client->Start();
|
||||
}
|
||||
@@ -130,6 +142,7 @@ JNIEXPORT void JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncClient_stop
|
||||
(JNIEnv*, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR(ptr);
|
||||
TimeSyncClient* client = reinterpret_cast<TimeSyncClient*>(ptr);
|
||||
client->Stop();
|
||||
delete client;
|
||||
@@ -144,6 +157,7 @@ JNIEXPORT jlong JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncClient_getOffset
|
||||
(JNIEnv*, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR_RETURN(ptr, 0);
|
||||
TimeSyncClient* client = reinterpret_cast<TimeSyncClient*>(ptr);
|
||||
return client->GetOffset();
|
||||
}
|
||||
@@ -157,6 +171,7 @@ JNIEXPORT jobject JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncClient_getLatestMetadata
|
||||
(JNIEnv* env, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR_RETURN(ptr, nullptr);
|
||||
TimeSyncClient* client = reinterpret_cast<TimeSyncClient*>(ptr);
|
||||
auto m{client->GetMetadata()};
|
||||
auto ret = env->NewObject(metadataClass, metadataCtor, m.offset, m.pingsSent,
|
||||
|
||||
@@ -24,6 +24,17 @@
|
||||
|
||||
using namespace wpi::tsp;
|
||||
|
||||
#define CHECK_PTR(ptr) \
|
||||
if (!ptr) { \
|
||||
fmt::println("Got invalid pointer?? {}:{}", __FILE__, __LINE__); \
|
||||
return; \
|
||||
}
|
||||
#define CHECK_PTR_RETURN(ptr, default) \
|
||||
if (!ptr) { \
|
||||
fmt::println("Got invalid pointer?? {}:{}", __FILE__, __LINE__); \
|
||||
return default; \
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
@@ -47,6 +58,7 @@ JNIEXPORT void JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncServer_start
|
||||
(JNIEnv*, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR(ptr);
|
||||
TimeSyncServer* server = reinterpret_cast<TimeSyncServer*>(ptr);
|
||||
server->Start();
|
||||
}
|
||||
@@ -60,6 +72,7 @@ JNIEXPORT void JNICALL
|
||||
Java_org_photonvision_jni_TimeSyncServer_stop
|
||||
(JNIEnv*, jclass, jlong ptr)
|
||||
{
|
||||
CHECK_PTR(ptr);
|
||||
TimeSyncServer* server = reinterpret_cast<TimeSyncServer*>(ptr);
|
||||
server->Stop();
|
||||
delete server;
|
||||
|
||||
Reference in New Issue
Block a user