# เฉลยพร้อมเหตุผล — IMU และข้อความขั้นประยุกต์

เปิดหลังทำ worksheet.csv และ message-worksheet.csv คำตอบอ้าง protocol1.0.0 และผล PC สังเคราะห์เดิม ไม่ใช่ผลอุปกรณ์จริง

## A1 · แกนและ specific force

FRD: X ไปหน้า, Y ไปขวา, Z ลง; roll บวกตามกฎมือขวารอบ X ในกรณีอุดมคติไม่มี noise วางราบนิ่งที่ roll=0 จะได้ az=-9.80665 m/s² และ ay=0 ตัวอย่าง CSV มี noise ตาม protocol จึงไม่ต้องเท่าค่านี้ทุกแถว สูตร atan2(-ay,-az) ใช้ภายใต้สมมติฐาน roll แกนเดียวนี้ อย่าคัดเครื่องหมายไปใช้กับ IMU ที่ยังไม่ตรวจกรอบพิกัด

## A2 · หน่วยและ bias

0.5×π/180 = 0.008726646 rad/s; bias คงที่0.5 deg/s สะสม10 s ทำให้มุมคลาดเคลื่อน5° ตัวเลข5° เป็นส่วนคลาดเคลื่อนจาก bias ที่ปลายช่วง ไม่ใช่ RMSE ทั้ง1001แถว (raw-gyro RMSE เดิม2.887792°) ช่วงแรก0–1 s ถูก generator ประกาศว่านิ่ง การลบ bias นี้ยังไม่ใช่การสอบเทียบเซนเซอร์จริง

## A3 · เวลาและน้ำหนัก

dt=10/1000=0.01 s; alpha=0.5/(0.5+0.01)=50/51≈0.980392157 ส่วน accelerometer หนัก1-alpha≈0.019607843 ต่อขั้นคาบนี้ หากคาบเปลี่ยนต้องใช้ dt จริง สูตรนี้เป็น complementary filter ของชุดฝึก ไม่ใช่ค่า alpha สากลของ flight stack

## A4 · เปรียบเทียบโดยมีขอบเขต

imu-motion: complementary RMSE2.386747° และ norm-gated RMSE0.005033° มี51ตัวอย่างที่ไม่ใช้ accel ระหว่าง5.00–5.50 s รวมปลายทั้งสอง (+3 m/s² ที่ Y ตาม protocol) gate ตรวจ |norm-g|≤0.3 m/s²; norm ใกล้g ไม่พิสูจน์ว่าไม่มี translation หรือแกนผิด ผลนี้จึงไม่รับรองว่าฟิลเตอร์ใช้ได้ดีกับ IMU จริงทุกสถานการณ์ ไม่เทียบ noise ของเซนเซอร์จริง และไม่ประมาณ yaw/EKF

## A5 · อายุและการคัดข้อความ

age=rx_ms-sample_ms ใน clock/boot เดียว ตรวจ future → stale → duplicate → out_of_order → accepted ตามลำดับ last_seq อัปเดตเฉพาะ accepted; accepted_gap ของแถวที่ไม่รับเป็น0

| data_row | rx_ms | seq | sample_ms | age_ms | disposition | accepted_gap |
|---|---|---|---|---|---|---|
|1|5|65533|0|5|accepted|0|
|2|15|65534|10|5|accepted|0|
|3|35|0|30|5|accepted|1|
|4|36|0|30|6|duplicate|0|
|5|40|65535|20|20|out_of_order|0|
|6|90|1|40|50|stale|0|
|7|95|2|80|15|accepted|1|
|8|110|3|120|-10|future_timestamp|0|
|9|120|3|100|20|accepted|0|
|10|170|4|130|40|accepted|0|
|11|181|5|140|41|stale|0|
|12|190|6|180|10|accepted|1|

ขอบเกณฑ์อายุ:40 ms ยังรับได้เมื่อ seq เดินหน้า;41 ms ปฏิเสธ stale อย่าสับสนกับเกณฑ์120 ms ของ toy control ในบทขั้นสูงซึ่งใช้คนละ protocol

## A6 · Wrap และ half-range

delta=(seq-last_seq) mod65536;65534→0 ได้2 จึงเดินหน้าและ gap=1 (ข้าม65535 ใน accepted stream);0→65535 ได้65535 จึงเก่า/กำกวมและปฏิเสธ ช่วงเดินหน้าที่รับคือ1..32767;0 ซ้ำ และ32768..65535 ไม่รับ การใช้ half-range ต้องมีขอบเขตอัตราข้อความ/ช่วงที่หายและ session ที่ชัดเจน เมื่อ reboot อย่าเอา last_seq เก่ามาต่อโดยไม่กำหนด session policy

## A7 · สิ่งที่นับได้

accepted7, duplicate1, out_of_order1, stale2, future_timestamp1 รวม12แถว; accepted-stream gaps3 เป็นช่องว่างในลำดับข้อความที่ผ่านกติกา ตัวอย่างนี้ยังมีบาง seq ในไฟล์แต่ถูกปฏิเสธ จึงใช้ gaps3 เป็นจำนวน RF packet loss ไม่ได้ ต้องมี sender/receiver capture, session, clock และเกณฑ์การจับคู่ที่เหมาะสมก่อนวัดการส่งจริง

## A8 · ปฏิเสธก่อนอัปเดตสถานะ

แถว8 age=-10 ถูกปฏิเสธ future_timestamp และไม่อัปเดต last_seq ซึ่งยังเป็น2 แถว9 seq3 age20 จึง delta1 และ accepted ถ้าอัปเดต last_seq จากแถว8 จะจัดแถว9เป็นduplicateผิด หากเป็น clock คนละเครื่อง rx-sample โดยตรงยังแปลเป็นอายุไม่ได้จนมีวิธีแปลงเวลาและขอบเขตความคลาดเคลื่อน boot/session ที่ประกาศไว้ ค่าติดลบใน fixture นี้เป็นข้อมูลผิดตามสมมติฐาน clock เดียว ไม่ใช่หลักฐานว่าเครือข่ายส่งย้อนเวลา

## ให้คะแนนเพื่อเลือกทบทวน

ข้อละ2: คำตอบถูก1 และเหตุผล/หน่วย/ข้อจำกัดถูก1 รวม16 เป็นเกณฑ์เสนอสำหรับตรวจตนเอง ไม่ใช่เกณฑ์ที่ผ่านการประเมินกับผู้เรียนจริง A1ต้องครบแกนและเครื่องหมาย;A2ครบสองค่า;A3ครบdt/alpha;A4ครบค่าผลและข้อจำกัด;A5ครบ12แถวและขอบอายุ;A6ครบdeltaสองค่า/half-range;A7ครบcountsและขอบเขตRF;A8ครบเหตุผลสองแถว/clock

หน่วยในเฟิร์มแวร์จริงอาจต่างจาก CSV นี้: [PX4 v1.16 SensorCombined](https://docs.px4.io/v1.16/en/msg_docs/SensorCombined) ระบุ gyro rad/s, acceleration m/s² ใน body FRD และ timestamp microseconds ตั้งแต่เริ่มระบบ จึงต้องอ่าน schema ของแหล่งข้อมูลจริงก่อนคำนวณ
