1010namespace fs = std::filesystem;
1111using namespace polyxml ::generated;
1212
13+ // Statically verify C++20 XmlModel concept
14+ static_assert (XmlModel<EntityMt>, " EntityMt must satisfy C++20 XmlModel concept" );
15+ static_assert (XmlModel<EntityMdt>, " EntityMdt must satisfy C++20 XmlModel concept" );
16+ static_assert (XmlModel<KinematicsType>, " KinematicsType must satisfy C++20 XmlModel concept" );
17+
1318struct LatticeEntity {
1419 std::string id;
15- std::string callsign;
20+ std::optional<std:: string> callsign;
1621 std::string timestamp;
17- std::string source_system;
18- std::string classification;
22+ std::optional<std:: string> source_system;
23+ std::optional<std:: string> classification;
1924 std::string status;
2025 double latitude = 0.0 ;
2126 double longitude = 0.0 ;
2227 double altitude_meters = 0.0 ;
23- double heading_degrees = 0.0 ;
24- double ground_speed_mps = 0.0 ;
25- double vertical_speed_mps = 0.0 ;
28+ std::optional<double > heading_degrees;
29+ std::optional<double > ground_speed_mps;
30+ std::optional<double > vertical_speed_mps;
31+ std::optional<double > airspeed_mps;
32+ std::optional<double > pitch_degrees;
33+ std::optional<double > roll_degrees;
34+ std::optional<std::string> flight_mode;
35+ std::optional<std::string> active_waypoint_id;
36+ std::optional<double > fuel_remaining_percent;
2637};
2738
28- // Simple zero-dependency JSON field extractor for benchmark demo
2939std::string extract_string_field (const std::string& json, const std::string& key) {
3040 std::regex re (" \" " + key + " \"\\ s*:\\ s*\" ([^\" ]+)\" " );
3141 std::smatch match;
@@ -63,12 +73,12 @@ EntityMt translate_lattice_to_uci(const LatticeEntity& lattice) {
6373 entity.object_state = ObjectStateEnum::Active;
6474
6575 // SecurityInformation & Header
66- entity.security_information .classification = ClassificationEnum::Secret ;
76+ entity.security_information .classification = ClassificationEnum::Unclassified ;
6777 entity.security_information .owner_producer = " USA" ;
6878
6979 entity.message_header .message_id = " MSG-" + lattice.id .substr (0 , 8 );
7080 entity.message_header .timestamp = lattice.timestamp ;
71- entity.message_header .originator_id = lattice.source_system ;
81+ entity.message_header .originator_id = lattice.source_system . value_or ( " LATTICE_MESH_NODE_DELTA " ) ;
7282
7383 // MessageData
7484 entity.message_data .entity_id .uuid = lattice.id ;
@@ -87,8 +97,14 @@ EntityMt translate_lattice_to_uci(const LatticeEntity& lattice) {
8797 entity.message_data .kinematics .heading = lattice.heading_degrees ;
8898 entity.message_data .kinematics .ground_speed = lattice.ground_speed_mps ;
8999 entity.message_data .kinematics .vertical_speed = lattice.vertical_speed_mps ;
100+ entity.message_data .kinematics .airspeed = lattice.airspeed_mps ;
101+ entity.message_data .kinematics .pitch = lattice.pitch_degrees ;
102+ entity.message_data .kinematics .roll = lattice.roll_degrees ;
90103
91104 entity.message_data .source_system = lattice.source_system ;
105+ entity.message_data .flight_mode = lattice.flight_mode ;
106+ entity.message_data .active_waypoint = lattice.active_waypoint_id ;
107+ entity.message_data .fuel_percentage = lattice.fuel_remaining_percent ;
92108
93109 return entity;
94110}
@@ -137,11 +153,29 @@ std::string serialize_uci_xml(const EntityMt& entity) {
137153 if (entity.message_data .kinematics .vertical_speed ) {
138154 oss << " <VerticalSpeed>" << *entity.message_data .kinematics .vertical_speed << " </VerticalSpeed>" ;
139155 }
156+ if (entity.message_data .kinematics .airspeed ) {
157+ oss << " <Airspeed>" << *entity.message_data .kinematics .airspeed << " </Airspeed>" ;
158+ }
159+ if (entity.message_data .kinematics .pitch ) {
160+ oss << " <Pitch>" << *entity.message_data .kinematics .pitch << " </Pitch>" ;
161+ }
162+ if (entity.message_data .kinematics .roll ) {
163+ oss << " <Roll>" << *entity.message_data .kinematics .roll << " </Roll>" ;
164+ }
140165 oss << " </Kinematics>" ;
141166
142167 if (entity.message_data .source_system ) {
143168 oss << " <SourceSystem>" << *entity.message_data .source_system << " </SourceSystem>" ;
144169 }
170+ if (entity.message_data .flight_mode ) {
171+ oss << " <FlightMode>" << *entity.message_data .flight_mode << " </FlightMode>" ;
172+ }
173+ if (entity.message_data .active_waypoint ) {
174+ oss << " <ActiveWaypoint>" << *entity.message_data .active_waypoint << " </ActiveWaypoint>" ;
175+ }
176+ if (entity.message_data .fuel_percentage ) {
177+ oss << " <FuelPercentage>" << *entity.message_data .fuel_percentage << " </FuelPercentage>" ;
178+ }
145179 oss << " </MessageData>" ;
146180 oss << " </EntityMT>" ;
147181 return oss.str ();
@@ -156,70 +190,106 @@ std::string serialize_uci_json(const EntityMt& entity) {
156190 oss << " \" ObjectState\" :\" " << to_string (*entity.object_state ) << " \" ," ;
157191 }
158192 oss << " \" MessageData\" :{" ;
159- oss << " \" EntityID\" :{\" UUID\" :\" " << entity.message_data .entity_id .uuid << " \" }," ;
193+ oss << " \" EntityID\" :{\" UUID\" :\" " << entity.message_data .entity_id .uuid << " \" " ;
194+ if (entity.message_data .entity_id .callsign ) {
195+ oss << " ,\" Callsign\" :\" " << *entity.message_data .entity_id .callsign << " \" " ;
196+ }
197+ oss << " }," ;
160198 oss << " \" EntityStatus\" :\" " << to_string (entity.message_data .entity_status ) << " \" ," ;
161- oss << " \" Kinematics\" :{\" Latitude\" :" << entity.message_data .kinematics .latitude << " ,\" Longitude\" :" << entity.message_data .kinematics .longitude << " }" ;
199+ oss << " \" Kinematics\" :{" ;
200+ oss << " \" Latitude\" :" << entity.message_data .kinematics .latitude << " ," ;
201+ oss << " \" Longitude\" :" << entity.message_data .kinematics .longitude ;
202+ if (entity.message_data .kinematics .airspeed ) {
203+ oss << " ,\" Airspeed\" :" << *entity.message_data .kinematics .airspeed ;
204+ }
205+ oss << " }" ;
206+ if (entity.message_data .flight_mode ) {
207+ oss << " ,\" FlightMode\" :\" " << *entity.message_data .flight_mode << " \" " ;
208+ }
162209 oss << " }}" ;
163210 return oss.str ();
164211}
165212
166213int main () {
167214 std::cout << " ================================================================================" << std::endl;
168215 std::cout << " 🛸 PolyXML: Anduril Lattice SDK ↔ USAF UCI C2 Bridge (Modern C++20)" << std::endl;
216+ std::cout << " Autonomous Flying Drone Airplane Telemetry (UNCLASSIFIED)" << std::endl;
169217 std::cout << " ================================================================================" << std::endl;
170218
171- std::string data_path = find_data_file ();
172- if (data_path .empty ()) {
219+ std::string data_file = find_data_file ();
220+ if (data_file .empty ()) {
173221 std::cerr << " Error: Could not locate data/lattice_entity.json" << std::endl;
174222 return 1 ;
175223 }
176224
177- std::ifstream file (data_path);
178- if (!file.is_open ()) {
179- std::cerr << " Error opening file: " << data_path << std::endl;
180- return 1 ;
181- }
182-
183- std::stringstream buffer;
184- buffer << file.rdbuf ();
185- std::string json_content = buffer.str ();
225+ std::ifstream file (data_file);
226+ std::string content ((std::istreambuf_iterator<char >(file)), std::istreambuf_iterator<char >());
186227
187228 LatticeEntity lattice;
188- lattice.id = extract_string_field (json_content, " id" );
189- lattice.callsign = extract_string_field (json_content, " callsign" );
190- lattice.timestamp = extract_string_field (json_content, " timestamp" );
191- lattice.source_system = extract_string_field (json_content, " source_system" );
192- lattice.status = extract_string_field (json_content, " status" );
193- lattice.latitude = extract_double_field (json_content, " latitude" );
194- lattice.longitude = extract_double_field (json_content, " longitude" );
195- lattice.altitude_meters = extract_double_field (json_content, " altitude_meters" );
196- lattice.heading_degrees = extract_double_field (json_content, " heading_degrees" );
197- lattice.ground_speed_mps = extract_double_field (json_content, " ground_speed_mps" );
198- lattice.vertical_speed_mps = extract_double_field (json_content, " vertical_speed_mps" );
199-
200- std::cout << " Ingesting Lattice Track: " << lattice.callsign << " (ID: " << lattice.id << " )" << std::endl;
229+ lattice.id = extract_string_field (content, " id" );
230+ lattice.callsign = extract_string_field (content, " callsign" );
231+ lattice.timestamp = extract_string_field (content, " timestamp" );
232+ lattice.source_system = extract_string_field (content, " source_system" );
233+ lattice.classification = extract_string_field (content, " classification" );
234+ lattice.status = extract_string_field (content, " status" );
235+
236+ lattice.latitude = extract_double_field (content, " latitude" );
237+ lattice.longitude = extract_double_field (content, " longitude" );
238+ lattice.altitude_meters = extract_double_field (content, " altitude_meters" );
239+
240+ double hdg = extract_double_field (content, " heading_degrees" );
241+ if (hdg != 0.0 ) lattice.heading_degrees = hdg;
242+
243+ double gs = extract_double_field (content, " ground_speed_mps" );
244+ if (gs != 0.0 ) lattice.ground_speed_mps = gs;
245+
246+ double vs = extract_double_field (content, " vertical_speed_mps" );
247+ if (vs != 0.0 ) lattice.vertical_speed_mps = vs;
248+
249+ double as = extract_double_field (content, " airspeed_mps" );
250+ if (as != 0.0 ) lattice.airspeed_mps = as;
251+
252+ double pitch = extract_double_field (content, " pitch_degrees" );
253+ if (pitch != 0.0 ) lattice.pitch_degrees = pitch;
201254
255+ double roll = extract_double_field (content, " roll_degrees" );
256+ if (roll != 0.0 ) lattice.roll_degrees = roll;
257+
258+ lattice.flight_mode = extract_string_field (content, " flight_mode" );
259+ lattice.active_waypoint_id = extract_string_field (content, " active_waypoint_id" );
260+ double fuel = extract_double_field (content, " fuel_remaining_percent" );
261+ if (fuel != 0.0 ) lattice.fuel_remaining_percent = fuel;
262+
263+ std::cout << " Ingesting Autonomous Drone Telemetry: "
264+ << (lattice.callsign ? *lattice.callsign : " N/A" )
265+ << " (ID: " << lattice.id << " )" << std::endl;
266+
267+ // 1. Ingest & Serialize to XML
202268 auto start_xml = std::chrono::high_resolution_clock::now ();
203269 EntityMt uci_entity = translate_lattice_to_uci (lattice);
204270 std::string xml_output = serialize_uci_xml (uci_entity);
205271 auto end_xml = std::chrono::high_resolution_clock::now ();
206- auto xml_us = std::chrono::duration_cast< std::chrono::nanoseconds >(end_xml - start_xml).count () / 1000.0 ;
272+ double xml_us = std::chrono::duration< double , std::micro >(end_xml - start_xml).count ();
207273
208274 std::cout << " \n [1] Generated USAF UCI XML Message (latency: " << xml_us << " μs):" << std::endl;
209275 std::cout << xml_output << std::endl;
210276
277+ assert (xml_output.find (" EntityMT" ) != std::string::npos);
278+ assert (xml_output.find (" UNCLASSIFIED" ) != std::string::npos);
279+ assert (xml_output.find (" FURY-UAV-01" ) != std::string::npos);
280+
281+ // 2. Inherent JSON Serialization
211282 auto start_json = std::chrono::high_resolution_clock::now ();
212283 std::string json_output = serialize_uci_json (uci_entity);
213284 auto end_json = std::chrono::high_resolution_clock::now ();
214- auto json_us = std::chrono::duration_cast< std::chrono::nanoseconds >(end_json - start_json).count () / 1000.0 ;
285+ double json_us = std::chrono::duration< double , std::micro >(end_json - start_json).count ();
215286
216287 std::cout << " \n [2] Generated Native JSON on Same Model (latency: " << json_us << " μs):" << std::endl;
217288 std::cout << json_output << std::endl;
218289
219- assert (xml_output.find (" EntityMT" ) != std::string::npos);
220- assert (xml_output.find (lattice.id ) != std::string::npos);
221- assert (xml_output.find (" CONFIRMED" ) != std::string::npos);
222- assert (uci_entity.validate ());
290+ // Verify C++20 default equality comparison
291+ EntityMt copy_entity = uci_entity;
292+ assert (copy_entity == uci_entity);
223293
224294 std::cout << " \n ✅ C++20 Lattice ↔ UCI Bridge executed successfully!" << std::endl;
225295 return 0 ;
0 commit comments