-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOutputPublisher.cpp
More file actions
89 lines (75 loc) · 3.03 KB
/
OutputPublisher.cpp
File metadata and controls
89 lines (75 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "io/OutputPublisher.h"
#include <networktables/NetworkTableInstance.h>
#include <chrono>
#include <vector>
#include "util/PoseUtils.h"
namespace {
/**
* @brief Helper function to serialize a Pose3d into a vector of doubles.
* Appends translation (x,y,z) and rotation quaternion (w,x,y,z).
* @param data The vector to append data to.
* @param pose The pose to serialize.
*/
void AppendPoseData(std::vector<double>& data, const frc::Pose3d& pose) {
data.push_back(pose.Translation().X().value());
data.push_back(pose.Translation().Y().value());
data.push_back(pose.Translation().Z().value());
const auto& q = pose.Rotation().GetQuaternion();
data.push_back(q.W());
data.push_back(q.X());
data.push_back(q.Y());
data.push_back(q.Z());
}
} // namespace
NTOutputPublisher::NTOutputPublisher(const std::string_view hardware_id,
const nt::NetworkTableInstance& nt_inst) {
const auto table =
nt_inst.GetTable("/cameras/" + std::string(hardware_id) + "/output");
constexpr nt::PubSubOptions options{
.periodic = 0.01, .sendAll = true, .keepDuplicates = true};
m_connection_status_pub = table->GetBooleanTopic("connected").Publish();
m_observations_pub =
table->GetDoubleArrayTopic("observations").Publish(options);
m_capture_fps_pub = table->GetIntegerTopic("capture_fps").Publish();
m_processing_fps_pub = table->GetIntegerTopic("processing_fps").Publish();
}
void NTOutputPublisher::SendConnectionStatus(const bool isConnected) {
m_connection_status_pub.Set(isConnected);
}
void NTOutputPublisher::SendAprilTagResult(const AprilTagResult& result) {
// --- Main observation data ---
// This contains the multi-tag pose estimate and corner angles.
std::vector<double> observation_data = {0.0};
if (!PoseUtils::isPoseZero(result.multi_tag_pose.pose_0)) {
const auto& obs = result.multi_tag_pose;
// Data format: [pose_count, error_0, x, y, z, qw, qx, qy, qz, (error_1,
// ...)]
if (obs.pose_1.has_value()) {
observation_data[0] = 2; // Flag for two poses
} else {
observation_data[0] = 1; // Flag for one pose
}
observation_data.push_back(obs.error_0);
AppendPoseData(observation_data, obs.pose_0);
if (obs.pose_1.has_value() && obs.error_1.has_value()) {
observation_data.push_back(obs.error_1.value());
AppendPoseData(observation_data, obs.pose_1.value());
}
}
// Append tag angles data
// Data format: [tag_id, c0_x, c0_y, c1_x, c1_y, ..., distance]
for (const auto& [tag_id, corners_angles, distance] : result.tag_angles) {
observation_data.push_back(tag_id);
observation_data.insert(observation_data.end(), corners_angles.begin(),
corners_angles.end());
observation_data.push_back(distance);
}
// Publish all data
m_observations_pub.Set(observation_data, result.timestamp);
}
void NTOutputPublisher::SendCaptureFPS(const uint8_t& fps) {
m_capture_fps_pub.Set(fps);
}
void NTOutputPublisher::SendProcessingFPS(const uint8_t& fps) {
m_processing_fps_pub.Set(fps);
}