← คู่มือ Mesh Networking — สื่อสารในที่ที่ไม่มีเสาสัญญาณ
LEVEL 3 · ระดับสูง
CoT และ ATAK — เอาทั้งทีมขึ้นแผนที่เดียวกัน
สิบสองบทที่ผ่านมาทำให้ข้อมูลเดินทางถึงกันได้ บทนี้ตอบว่าแล้วจะส่งอะไร เพื่อให้คนในสนามเห็นภาพเดียวกัน
13.1 ปัญหาที่ไม่ใช่ปัญหาเครือข่าย
ต่อให้เครือข่ายสมบูรณ์แบบ ถ้าแต่ละเครื่องพูดคนละภาษาก็ยังใช้งานไม่ได้ วิทยุยี่ห้อหนึ่งส่งพิกัดเป็น JSON อีกยี่ห้อส่งเป็นไบนารีของตัวเอง — สองทีมที่ถือคนละยี่ห้อจึงเห็นกันไม่ได้ ทั้งที่คลื่นถึงกันดี
ATAK (Android Team Awareness Kit) คือแอปแผนที่ที่แสดงตำแหน่งของทุกคนในทีมแบบเรียลไทม์ และภาษาที่มันใช้ชื่อ CoT (Cursor on Target) ซึ่งเป็น XML รูปแบบง่าย ๆ ที่กลายเป็นภาษากลางของงานสายนี้ไปแล้ว
13.2 พิสูจน์ด้วยตาเอง — สร้างข้อความจริงหนึ่งใบ
import xml.etree.ElementTree as ET
def make_cot(uid, lat, lon, cot_type="a-f-G-U-C", callsign="RESCUE-1"):
"""สร้างข้อความ Cursor on Target หนึ่งใบ"""
ev = ET.Element("event", {
"version": "2.0", "uid": uid, "type": cot_type,
"time": "2026-08-31T09:15:00Z", # เวลาที่สร้าง
"start": "2026-08-31T09:15:00Z", # เริ่มมีผล
"stale": "2026-08-31T09:20:00Z", # หมดอายุ — ครบแล้วหมุดจางหายเอง
"how": "m-g",
})
ET.SubElement(ev, "point", {"lat": f"{lat}", "lon": f"{lon}", "hae": "120.0",
"ce": "9999999.0", "le": "9999999.0"})
detail = ET.SubElement(ev, "detail")
ET.SubElement(detail, "contact", {"callsign": callsign})
ET.SubElement(detail, "__group", {"name": "Cyan", "role": "Team Member"})
return ET.tostring(ev, encoding="unicode")
xml = make_cot("RESCUE-1-abc123", 13.6512, 100.4961)
root = ET.fromstring(xml)
pt = root.find("point")
print(f"{root.find('detail/contact').get('callsign')} อยู่ที่ {pt.get('lat')}, {pt.get('lon')}")
print(f"ชนิด {root.get('type')} · หมดอายุ {root.get('stale')} · ขนาด {len(xml.encode('utf-8'))} ไบต์")ผลรันจริง
RESCUE-1 อยู่ที่ 13.6512, 100.4961
ชนิด a-f-G-U-C · หมดอายุ 2026-08-31T09:20:00Z · ขนาด 334 ไบต์13.3 สามอย่างในรูปแบบนี้ที่ออกแบบมาเพื่อเครือข่ายแบบเมชโดยเฉพาะ
หนึ่ง — stale คือการยอมรับว่าข้อมูลเน่า ทุกข้อความบอกวันหมดอายุของตัวเองมาด้วย ถ้าไม่มีใบใหม่มาก่อนถึงเวลานั้น หมุดบนแผนที่จะจางหายไปเอง · นี่คือประโยคแก่นของบทที่ 4 ที่ถูกเขียนลงไปในรูปแบบข้อมูลโดยตรง — ระบบไม่แสร้งว่ารู้ตำแหน่งปัจจุบันของทุกคน มันแสดงแค่สิ่งที่รู้ล่าสุดพร้อมบอกว่ารู้มานานแค่ไหน
สอง — 334 ไบต์ต่อใบ เล็กพอที่จะยัดลงวิทยุย่านต่ำที่ช้ามากได้ ถ้าทีมหกคนส่งตำแหน่งทุก 5 วินาที นั่นคือ 6 × 334 × 8 ÷ 5 = ราว 3,200 bps ซึ่งวิทยุ 250 kbps ในบทที่ 8 รับไหวสบาย ๆ
สาม — uid คงที่ต่อคน ไม่ใช่ต่อข้อความ ทำให้ใบใหม่ทับใบเก่าได้เอง แผนที่จึงไม่มีหมุดซ้ำของคนเดียวกันเรียงกันเป็นแถว
13.4 ข้อควรระวังที่กระทบ routing ตรง ๆ
ข้อความตำแหน่งเป็นข้อมูลที่ ส่งซ้ำได้ ไม่จำเป็นต้องถึงทุกใบ — ใบที่หายไปจะถูกแทนที่ด้วยใบถัดไปในอีกห้าวินาทีอยู่แล้ว การพยายามรับประกันว่าทุกใบต้องถึง (ส่งซ้ำจนกว่าจะได้ใบตอบรับ) จึงเป็นการเผาอากาศทิ้งเปล่า ๆ กับข้อมูลที่กำลังจะหมดอายุอยู่แล้ว
ขณะที่เสียงพูดหรือคำสั่งภารกิจเป็นคนละเรื่อง — ใบที่หายคือเนื้อหาที่หายจริง
⇒ เครือข่ายภาคสนามที่ออกแบบดีจะแยกชั้นความสำคัญของข้อมูล แล้วปฏิบัติกับมันคนละแบบ ไม่ใช่ยัดทุกอย่างลงท่อเดียวแล้วหวังว่าจะพอ