Skip to content

Commit 4d5b500

Browse files
authored
Merge pull request #895 from meshtastic/takv2_geometry
Takv2 geometry (missed commits)
2 parents c9067da + 793e274 commit 4d5b500

1 file changed

Lines changed: 266 additions & 0 deletions

File tree

meshtastic/atak.proto

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,141 @@ message CasevacReport {
14981498
* "Victor 6"). Capped tight in options.
14991499
*/
15001500
string frequency = 15;
1501+
1502+
// --- v2.x medline extensions (tags 16–33) --------------------------------
1503+
//
1504+
// Fields 16+ cost a 2-byte tag instead of 1 byte, but they're usually
1505+
// sparse so the on-wire delta is modest when most stay unset. A fully
1506+
// populated CASEVAC with 13 free-text fields + 2 ZMIST entries can run
1507+
// 200-400 bytes compressed, i.e. potentially over the 237 B LoRa MTU.
1508+
// Callers that hit the MTU on the `compressWithRemarksFallback` path
1509+
// SHOULD strip the tier-2 situational fields (tags 28-32 + terrain_other_detail)
1510+
// before dropping the packet entirely. See README "CASEVAC tier-2 stripping".
1511+
1512+
/*
1513+
* Short title / MEDEVAC identifier (e.g. "EAGLE.15.181230"). Usually the
1514+
* same as the envelope callsign but ATAK sometimes carries a distinct
1515+
* ops-number here.
1516+
*/
1517+
string title = 16;
1518+
/*
1519+
* Primary medline free-text — the single most clinically important line
1520+
* on a MEDLINE form (e.g. "2 urgent litter patients, smoke on approach").
1521+
* MUST be preserved under MTU pressure as long as any casevac is sent.
1522+
*/
1523+
string medline_remarks = 17;
1524+
1525+
/*
1526+
* Line 3 (newer ATAK format): patient counts by precedence level.
1527+
* Coexists with the enum-style `precedence` field (tag 1) — older ATAK
1528+
* emits a single enum, newer ATAK emits these counts, and both can be
1529+
* set simultaneously. Senders populate whichever style(s) the source
1530+
* XML had; receivers prefer counts when non-zero.
1531+
*/
1532+
uint32 urgent_count = 18;
1533+
uint32 urgent_surgical_count = 19;
1534+
uint32 priority_count = 20;
1535+
uint32 routine_count = 21;
1536+
uint32 convenience_count = 22;
1537+
1538+
/*
1539+
* Line 4 supplementary: free-text description of non-standard equipment
1540+
* (e.g. "Blood warmer"). Pairs with the `equipment_flags` bitfield.
1541+
*/
1542+
string equipment_detail = 23;
1543+
/*
1544+
* Line 1 override: MGRS grid when distinct from the event anchor point
1545+
* (e.g. "34T CQ 12345 67890"). Event lat/lon/hae still carries the
1546+
* numeric location; this field preserves the exact MGRS string the
1547+
* medic entered.
1548+
*/
1549+
string zone_protected_coord = 24;
1550+
/*
1551+
* Line 9 supplementary: slope direction (e.g. "N", "NE", "SSW") when
1552+
* `terrain_flags` bit 0 (slope) is set.
1553+
*/
1554+
string terrain_slope_dir = 25;
1555+
/*
1556+
* Line 9 supplementary: free-text description of "other" terrain hazards
1557+
* (e.g. "Loose debris on west edge") when `terrain_flags` bit 5 (other)
1558+
* is set. Tier-2 strippable under MTU pressure.
1559+
*/
1560+
string terrain_other_detail = 26;
1561+
/*
1562+
* Line 7 supplementary: how the zone is being marked right now
1563+
* (e.g. "Orange smoke", "VS-17 panel"). Complements the structured
1564+
* `hlz_marking` enum with a specific human-readable description.
1565+
*/
1566+
string marked_by = 27;
1567+
1568+
// --- Tier-2 situational awareness (stripped first under MTU pressure) ---
1569+
// These fields are free-text context that helps the receiver plan the
1570+
// approach but aren't strictly required to evacuate the patient.
1571+
1572+
/*
1573+
* Nearby obstacles on the approach (e.g. "Power lines north of HLZ").
1574+
*/
1575+
string obstacles = 28;
1576+
/*
1577+
* Wind direction and speed (e.g. "270 at 12 kts").
1578+
*/
1579+
string winds_are_from = 29;
1580+
/*
1581+
* Friendly forces posture near the pickup zone
1582+
* (e.g. "Squad east of HLZ").
1583+
*/
1584+
string friendlies = 30;
1585+
/*
1586+
* Known or suspected enemy positions near the pickup zone
1587+
* (e.g. "Possible enemy on south ridge").
1588+
*/
1589+
string enemy = 31;
1590+
/*
1591+
* Free-text description of the HLZ itself
1592+
* (e.g. "Primary HLZ is soccer field").
1593+
*/
1594+
string hlz_remarks = 32;
1595+
1596+
/*
1597+
* Per-patient clinical records. Each entry is one patient's ZMIST card
1598+
* (Zap number / Mechanism / Injuries / Signs / Treatment). Repeatable —
1599+
* a mass-casualty event can carry 1-6 entries in practice, limited by
1600+
* the 237 B LoRa MTU.
1601+
*/
1602+
repeated ZMistEntry zmist = 33;
1603+
}
1604+
1605+
/*
1606+
* Per-patient clinical summary record — one entry per patient in a CASEVAC.
1607+
* Maps directly to ATAK's <zMist> child element inside <zMistsMap>.
1608+
* All fields are optional free-text; senders populate what they have.
1609+
*/
1610+
message ZMistEntry {
1611+
/*
1612+
* Patient identifier / sequence label (e.g. "ZMIST-1", "ZMIST-2").
1613+
*/
1614+
string title = 1;
1615+
/*
1616+
* Zap number — unique patient tracking ID (often a terse code like
1617+
* "Gunshot" or a serial).
1618+
*/
1619+
string z = 2;
1620+
/*
1621+
* Mechanism of injury (e.g. "Penetrating trauma", "Blast injury").
1622+
*/
1623+
string m = 3;
1624+
/*
1625+
* Injuries observed (e.g. "Left thigh", "Concussion").
1626+
*/
1627+
string i = 4;
1628+
/*
1629+
* Signs / vital stats (e.g. "Stable", "Priority", "BP 110/70").
1630+
*/
1631+
string s = 5;
1632+
/*
1633+
* Treatment given (e.g. "Tourniquet 1810Z", "O2 administered").
1634+
*/
1635+
string t = 6;
15011636
}
15021637

15031638
/*
@@ -1587,6 +1722,114 @@ message TaskRequest {
15871722
string note = 6;
15881723
}
15891724

1725+
/*
1726+
* Weather annotation from <environment> CoT detail element.
1727+
*
1728+
* Attaches to any TAKPacketV2 regardless of payload_variant — an Aircraft,
1729+
* PLI, or Marker can all carry observed conditions at the emitting station.
1730+
* ATAK-CIV ships an XSD for <environment> but no dedicated handler, so the
1731+
* element round-trips through the generic detail pipeline; this message
1732+
* promotes it to a first-class structured field.
1733+
*
1734+
* Target wire cost: ~6-8 bytes compressed with a fully populated instance.
1735+
*
1736+
* Named `TAKEnvironment` (not just `Environment`) because the bare name
1737+
* collides with `SwiftUI.Environment` — every SwiftUI view in a consuming
1738+
* iOS app uses the `@Environment` property wrapper, and importing the
1739+
* generated proto module would make `Environment` ambiguous in every one
1740+
* of those files. The `TAK` prefix matches the convention used by the
1741+
* outer `TAKPacketV2` wrapper and is unambiguous across all target
1742+
* languages (Swift, Kotlin, Python, TypeScript, C#).
1743+
*/
1744+
message TAKEnvironment {
1745+
/*
1746+
* Temperature in deci-degrees Celsius. 225 = 22.5°C.
1747+
* Range covers -50°C to +50°C (-500 to +500) which spans every realistic
1748+
* outdoor TAK deployment. sint32 because negative temps are common in
1749+
* cold-weather ops.
1750+
*/
1751+
sint32 temperature_c_x10 = 1;
1752+
/*
1753+
* Wind direction in whole degrees, 0-359. "Direction FROM" per
1754+
* meteorological convention (matches CoT / ATAK).
1755+
*/
1756+
uint32 wind_direction_deg = 2;
1757+
/*
1758+
* Wind speed in cm/s. Matches the unit of TAKPacketV2.speed for
1759+
* consistency. 1200 = 12.00 m/s = ~27 mph.
1760+
*/
1761+
uint32 wind_speed_cm_s = 3;
1762+
}
1763+
1764+
/*
1765+
* Sensor field-of-view cone from <sensor> CoT detail element.
1766+
*
1767+
* Encodes the 8 geometry attributes that ATAK-CIV's SensorDetailHandler
1768+
* reads from the wire; drops the 9 visual-styling attributes that are
1769+
* receiver-side render hints (fovAlpha, fovRed/Green/Blue, strokeColor,
1770+
* strokeWeight, displayMagneticReference, hideFov, fovLabels, rangeLines).
1771+
* The receiving ATAK client restores those from its own defaults, same as
1772+
* every other CoT carried over Meshtastic today.
1773+
*
1774+
* Attaches to any TAKPacketV2 — a PLI with a sensor on the operator's head,
1775+
* an Aircraft with a FLIR turret, a Marker dropped on a UAV.
1776+
* Target wire cost: ~7-14 bytes compressed (dominated by model string).
1777+
*/
1778+
message SensorFov {
1779+
/*
1780+
* Coarse sensor category, inferred from `model` on parse when the source
1781+
* XML doesn't label it. Receivers that render differently per sensor
1782+
* class (thermal overlay vs daylight cone) use this.
1783+
*/
1784+
enum SensorType {
1785+
SensorType_Unspecified = 0;
1786+
SensorType_Camera = 1; // daylight / general optical
1787+
SensorType_Thermal = 2; // FLIR, thermal imager
1788+
SensorType_Laser = 3; // rangefinder, LRF, designator
1789+
SensorType_Nvg = 4; // night vision goggles
1790+
SensorType_Rf = 5; // radio/radar direction-finding
1791+
SensorType_Other = 6;
1792+
}
1793+
1794+
SensorType type = 1;
1795+
/*
1796+
* Azimuth in whole degrees, 0-359. "Pointing direction" of the cone axis,
1797+
* measured clockwise from true north. Whole degrees match ATAK-CIV's
1798+
* SensorDetailHandler default (270°) and save varint bytes over centi-deg.
1799+
*/
1800+
uint32 azimuth_deg = 2;
1801+
/*
1802+
* Maximum range of the cone in meters.
1803+
* Optional — if unset, receivers should use the ATAK-CIV default of 100m.
1804+
*/
1805+
optional uint32 range_m = 3;
1806+
/*
1807+
* Horizontal field of view in whole degrees (cone's angular width).
1808+
* ATAK-CIV default is 45°.
1809+
*/
1810+
uint32 fov_horizontal_deg = 4;
1811+
/*
1812+
* Vertical field of view in whole degrees. ATAK-CIV default is 45°.
1813+
* Optional — a value of 0 means "not set / use horizontal FOV".
1814+
*/
1815+
uint32 fov_vertical_deg = 5;
1816+
/*
1817+
* Elevation angle in whole degrees. Positive = up, negative = down.
1818+
* Range -90 to +90. sint32 for varint efficiency on small negatives.
1819+
*/
1820+
sint32 elevation_deg = 6;
1821+
/*
1822+
* Roll (camera tilt) in whole degrees, -180 to +180.
1823+
* Optional — use 0 if the sensor doesn't track roll.
1824+
*/
1825+
sint32 roll_deg = 7;
1826+
/*
1827+
* Free-form device model identifier, e.g. "FLIR-Boson-640", "SEEK".
1828+
* Optional — empty string means "unknown model" (ATAK-CIV default).
1829+
*/
1830+
string model = 8;
1831+
}
1832+
15901833
/*
15911834
* ATAK v2 packet with expanded CoT field support and zstd dictionary compression.
15921835
* Sent on ATAK_PLUGIN_V2 port. The wire payload is:
@@ -1695,6 +1938,29 @@ message TAKPacketV2 {
16951938
* Empty string (proto3 default) means no remarks were present.
16961939
*/
16971940
string remarks = 24;
1941+
1942+
// --- Sensor / environment annotations ----------------------------------
1943+
//
1944+
// Both fields are OPTIONAL and attach to any payload_variant. They
1945+
// describe observed conditions at the emitting station — a PLI with
1946+
// environment data, an Aircraft with a sensor cone, a Marker with both.
1947+
// Absent by default; presence is signaled by the message being non-null.
1948+
1949+
/*
1950+
* Observed weather conditions (temperature, wind). From <environment>.
1951+
* Type is `TAKEnvironment`, not `Environment`, to avoid colliding with
1952+
* SwiftUI's `@Environment` property wrapper in iOS consumers.
1953+
*/
1954+
optional TAKEnvironment environment = 25;
1955+
/*
1956+
* Sensor field-of-view cone (camera, FLIR, laser, etc.). From <sensor>.
1957+
*/
1958+
optional SensorFov sensor_fov = 26;
1959+
1960+
reserved 27, 28, 29;
1961+
// Tags 27, 28, 29 reserved for future top-level annotations before the
1962+
// payload_variant oneof resumes at 30.
1963+
16981964
/*
16991965
* The payload of the packet
17001966
*/

0 commit comments

Comments
 (0)