How to Convert from NT Entry to Publisher/Subscriber?

At the urging of AdvantageScope (AS) I’m changing how my roboRIO code sends the robot Pose3D to AS.

Old way is NetworkTableEntry and new way is type-specific Publisher and Subscriber classes.

I have a separate Pose3D entry for each of the different tags detected in a camera frame.

old code:

Once:

    NetworkTable tagsTable = NetworkTableInstance.getDefault().getTable("apriltags");

Periodically:

    tagsTable
	  .getEntry("robotPose3D_" + detection.getId()) // pose according to this tag
	  .setDoubleArray(
		new double[] {
		  robotInFieldFrame.getTranslation().getX(),
		  robotInFieldFrame.getTranslation().getY(),
		  robotInFieldFrame.getTranslation().getZ(),
		  robotInFieldFrame.getRotation().getQuaternion().getW(),
		  robotInFieldFrame.getRotation().getQuaternion().getX(),
		  robotInFieldFrame.getRotation().getQuaternion().getY(),
		  robotInFieldFrame.getRotation().getQuaternion().getZ()
        });

The new code below works but only for an instant because the publish() reaches its capacity quickly - obviously not intended to be in the periodic loop.

failing new code:

once:
NetworkTable tagsTable = NetworkTableInstance.getDefault().getTable("apriltags");

periodically:
StructPublisher<Pose3d> pubPose = tagsTable
  .getStructTopic("robotPose3D_" + detection.getId(), Pose3d.struct).publish();

pubPose.set(robotPose);

How can I publish the dynamic, camera frame-by-frame, determination of all the tag ids and associated poses and retain the tag id in NetworkTables on the display in some manner - sub-table, channel, entry?

Correct, you should not be calling publish() periodically. That creates a publisher every time it is called. The StructPublisher should be the variable you store, and the only thing you should call periodically is set().

If you want this whole set of things to be a Struct, you can create custom ones (which can include other structs) and publish them or arrays of them. See Pose3d (and Pose3dStruct) for an example implementation of how to do this.

Thanks. It sounds like all of the possible named Topics have to be predefined and published before I run the periodic. And then in the periodic I need logic to select the correct predefined Topic to set() it.

In the old way the Entries could be named, defined, and set on the fly in the periodic without any previous knowledge of what Entry was going to be needed.

Correct. There’s an internal cache for string name to NetworkTableEntry. That is not the case for the typed Publisher/Subscriber/Entry usage.