STAR
Cal STAR โ€” firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
send_fake_pt.cpp
Go to the documentation of this file.
1/**
2 * Simple test to send fake RawPTMessage data to Elodin DB
3 * Uses our message formats and Elodin protocol
4 */
5
6#include <array>
7#include <chrono>
8#include <cstdint>
9#include <iomanip>
10#include <iostream>
11#include <thread>
12#include <vector>
13
14// Our includes
15#include "../../utl/db.hpp"
16#include "../include/elodin/DatabaseConfig.hpp"
17#include "../include/elodin/ElodinClient.hpp"
19
20using namespace vtable;
21using namespace vtable::builder;
22
23int main(int argc, char* argv[]) {
24 if (argc < 2) {
25 std::cerr << "Usage: " << argv[0] << " <db_port> [message_count]" << std::endl;
26 std::cerr << "Example: " << argv[0] << " 2240 10" << std::endl;
27 return 1;
28 }
29
30 uint16_t port = std::stoi(argv[1]);
31 int message_count = (argc > 2) ? std::stoi(argv[2]) : 10;
32
33 std::cout << "\n๐Ÿงช Sending fake RawPTMessage to Elodin" << std::endl;
34 std::cout << "===================================" << std::endl;
35 std::cout << "Database: 127.0.0.1:" << port << std::endl;
36 std::cout << "Messages: " << message_count << std::endl;
37 std::cout << "Packet ID: [0x20, 0x00]" << std::endl;
38 std::cout << "===================================\n" << std::endl;
39
40 try {
41 // Connect to Elodin DB
42 daq_comms::elodin::ElodinClient client;
43 if (!client.connect("127.0.0.1", port)) {
44 std::cerr << "โŒ Failed to connect to Elodin DB: " << client.last_error() << std::endl;
45 return 1;
46 }
47 std::cout << "โœ… Connected to Elodin DB" << std::endl;
48
49 // Register VTable for RawPTMessage
50 // RawPTMessage: uint64_t timestamp_ns, uint8_t channel_id, uint32_t raw_adc_counts,
51 // uint32_t sample_timestamp_ms, uint8_t status_flags
52 // Total: 8 + 1 + 4 + 4 + 1 = 18 bytes
53 if (!daq_comms::elodin::DatabaseConfig::register_tables(client)) {
54 std::cerr << "โŒ Failed to register tables" << std::endl;
55 return 1;
56 }
57 std::cout << "โœ… Registered VTables" << std::endl;
58
59 // Wait for Elodin to process VTable registrations
60 // FSW waits 500ms, but let's wait much longer to ensure VTables are fully processed
61 std::cout << "โณ Waiting 5 seconds for Elodin to fully process VTable registrations..."
62 << std::endl;
63 std::this_thread::sleep_for(std::chrono::milliseconds(5000));
64
65 // Send fake RawPTMessage data
66 std::cout << "๐Ÿ“ค Starting data transmission..." << std::endl;
67 std::cout << " Sending " << message_count << " RawPTMessage(s) to Elodin" << std::endl;
68 std::cout << " Rate: ~10 Hz (100ms between messages)" << std::endl;
69 std::cout << std::endl;
70 auto start_time = std::chrono::steady_clock::now();
71
72 std::array<uint8_t, 2> pt_packet_id{0x20, 0x00}; // PT_PACKET_ID
73
74 for (int i = 0; i < message_count; ++i) {
76
77 // Generate fake data
78 auto now = std::chrono::steady_clock::now();
79 auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - start_time);
80 uint64_t timestamp_ns = elapsed.count();
81 uint8_t channel_id = i % 3; // Cycle through channels 0, 1, 2
82 uint32_t raw_adc_counts = 1000 + i * 10; // Fake ADC reading
83 uint32_t sample_timestamp_ms = i * 100; // Fake embedded timestamp
84 uint8_t status_flags = 0; // Good status
85
86 pt_msg.setField<0>(timestamp_ns);
87 pt_msg.setField<1>(channel_id);
88 pt_msg.setField<2>(std::array<uint8_t, 3>{0, 0, 0}); // Padding bytes (must be zeros)
89 pt_msg.setField<3>(raw_adc_counts);
90 pt_msg.setField<4>(sample_timestamp_ms);
91 pt_msg.setField<5>(status_flags);
92
93 // Debug: Hex dump first message to compare with FSW
94 if (i == 0) {
95 // Use the same serialize_msg that ElodinClient uses
96 auto debug_buf =
97 daq_comms::elodin::ElodinClient::serialize_msg(pt_packet_id, pt_msg);
98
99 std::cout << "\n[DEBUG] First message hex dump (" << debug_buf.size()
100 << " bytes):\n";
101 for (size_t j = 0; j < debug_buf.size(); j++) {
102 std::cout << std::hex << std::setw(2) << std::setfill('0')
103 << (int)static_cast<uint8_t>(debug_buf[j]) << " ";
104 if ((j + 1) % 8 == 0)
105 std::cout << "\n";
106 }
107 std::cout << std::dec << "\n";
108 std::cout << "[DEBUG] Expected: len(4)=" << std::hex << (18 + 4) << std::dec
109 << ", type=1, packet_id=[0x20,0x00], request_id=0\n";
110 }
111
112 // Publish to Elodin
113 if (!client.publish(pt_packet_id, pt_msg)) {
114 std::cerr << "โŒ Failed to publish message #" << (i + 1) << std::endl;
115 continue;
116 }
117
118 if (i < 5) {
119 std::cout << "[send_fake_pt] โœ… Sent #" << (i + 1)
120 << " (channel=" << (int)channel_id << ", adc=" << raw_adc_counts
121 << ", timestamp=" << timestamp_ns << ")" << std::endl;
122 } else if (i % 50 == 0) {
123 std::cout << "[send_fake_pt] ๐Ÿ“Š Progress: " << (i + 1) << "/" << message_count
124 << " messages sent" << std::endl;
125 }
126
127 // Flush after each message to ensure immediate delivery (like FSW)
128 client.flush_buffer();
129 std::this_thread::sleep_for(std::chrono::milliseconds(100));
130 }
131
132 // Final flush
133 client.flush_buffer();
134
135 auto end_time = std::chrono::steady_clock::now();
136 auto duration =
137 std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
138
139 std::cout << "\n===================================" << std::endl;
140 std::cout << "โœ… Transmission Complete!" << std::endl;
141 std::cout << " Messages sent: " << message_count << std::endl;
142 std::cout << " Duration: " << duration.count() << " ms" << std::endl;
143 std::cout << " Average rate: " << (message_count * 1000.0 / duration.count()) << " msg/s"
144 << std::endl;
145 std::cout << "===================================" << std::endl;
146 std::cout << "\n๐Ÿ“Š View data in Elodin editor:" << std::endl;
147 std::cout << " elodin editor ~/.local/share/elodin/test_pt_db" << std::endl;
148 std::cout << std::endl;
149
150 client.disconnect();
151
152 } catch (const std::exception& e) {
153 std::cerr << "โŒ Error: " << e.what() << std::endl;
154 return 1;
155 }
156
157 return 0;
158}
static const emmc_port_t port
Definition emmc_stm32.c:210
CommsMessage< uint64_t, uint8_t, std::array< uint8_t, 3 >, uint32_t, uint32_t, uint8_t > RawPTMessage
Raw Pressure Transducer sample message for Elodin.
static bool elapsed(uint32_t now, uint32_t then, uint32_t interval)
Definition self_test.c:10
void setField(ValueType &&value)
int main()