วินิจฉัยจาก log
UAT 303 การตรวจสอบและบำรุงรักษาระบบอากาศยานไร้คนขับ
บทเรียน
เมื่อเรียนจบโมดูลนี้ ผู้เรียนจะสามารถ
- ตั้งสมมติฐานหลายข้อจากอาการ แล้วเลือกข้อมูลใน log ที่แยกสมมติฐานได้
- ใช้การแปลงฟูเรียร์ (FFT) ของข้อมูลความเร่งแยกความไม่สมดุลของใบพัดออกจากการสั่นปกติ
- เปรียบเทียบเซนเซอร์ที่ซ้ำกันเพื่อหาเซนเซอร์ที่ผิดปกติ
- เขียนผลวินิจฉัยที่แยกหลักฐานออกจากข้อสันนิษฐาน
ทำไมต้องรู้
UAT 321 สอนวงจรการวินิจฉัย การหาความต้านทานภายในจาก log และความไม่สมดุลของมอเตอร์จากค่าเอาต์พุตไปแล้ว โมดูลนี้เพิ่มเครื่องมือสองอย่างที่ช่างระดับสูงใช้: ดูการสั่นในโดเมนความถี่ และ เทียบเซนเซอร์ที่ซ้ำกัน หน่วยความรู้เรื่องการวินิจฉัยจากอาการและ log ของคลังความรู้โดรนเตือนว่า log เป็นหลักฐานของค่าที่ระบบบันทึก ไม่ได้แสดงความจริงทุกด้าน สัญญาณผิดปกติอาจมาจากการวัด สายเชื่อมต่อ หรือระบบย่อยอื่น การวินิจฉัยจึงต้องเริ่มจากสมมติฐานหลายข้อ กรณีของวิชานี้คือฝูงโดรนสำรวจ 4 ลำของหน่วยงานหนึ่ง ข้อมูลในตัวอย่างเป็นข้อมูลจำลอง
จากอาการสู่สมมติฐาน
อาการ “โดรนลำที่ 3 สั่นมากขึ้นหลังลงจอดแรง” มีสาเหตุที่เป็นไปได้หลายข้อ เช่น ใบพัดบิ่นหรือไม่สมดุล เพลามอเตอร์คด ฐานกันสั่นของตัวควบคุมการบินหลวม หรือโครงร้าวจนเกิดการสั่นพ้อง แต่ละสมมติฐานทิ้งร่องรอยต่างกันในข้อมูล ความไม่สมดุลของชิ้นที่หมุนสร้างแรงที่ความถี่เท่ากับการหมุนหนึ่งรอบ () ส่วนแรงจากใบพัดแต่ละใบที่ผ่านแขนสร้างการสั่นที่ความถี่ใบพัดผ่าน () ซึ่งมีอยู่แม้โดรนปกติ เอกสาร ArduPilot เรื่อง harmonic notch และ in-flight FFT อธิบายว่าการสั่นของโดรนหลายใบพัดมาจากความถี่การหมุนของมอเตอร์และฮาร์มอนิกของมัน การแปลงฟูเรียร์ (FFT) แยกสัญญาณความเร่งออกเป็นส่วนประกอบตามความถี่ จึงเห็นว่าการสั่นเพิ่มที่ความถี่ใด ความละเอียดความถี่เท่ากับหนึ่งหารด้วยความยาวของข้อมูล
ตัวอย่างที่ 1 แยกความไม่สมดุลด้วย FFT
ข้อมูลความเร่งแกน X จำลองที่อัตราสุ่ม 1,000 Hz นาน 3 วินาที ขณะลอยตัวที่ 5,000 rpm ใบพัด 2 ใบ ก่อนและหลังลงจอดแรง
import numpy as np
FS, T = 1000, 3.0 # Hz, s
RPM, BLADES = 5000, 2
f1 = RPM / 60
t = np.arange(0, T, 1 / FS)
rng = np.random.default_rng(7)
def accel(a_1x): # m/s² ส่วนที่ 1x จากความไม่สมดุล
return a_1x * np.sin(2 * np.pi * f1 * t) + 3.0 * np.sin(2 * np.pi * BLADES * f1 * t) + rng.normal(0, 1.0, t.size)
print(f"1x = {f1:.1f} Hz, blade pass = {BLADES * f1:.1f} Hz, resolution = {1 / T:.2f} Hz")
for name, a in (("before", 0.8), ("after", 6.0)):
x = accel(a)
amp = np.abs(np.fft.rfft(x)) * 2 / x.size
f = np.fft.rfftfreq(x.size, 1 / FS)
k1, kb = np.argmin(abs(f - f1)), np.argmin(abs(f - BLADES * f1))
print(f"{name:<6} peak at {f[np.argmax(amp)]:.1f} Hz | 1x {amp[k1]:.2f} | blade pass {amp[kb]:.2f} | 1x/blade {amp[k1] / amp[kb]:.2f}")
1x = 83.3 Hz, blade pass = 166.7 Hz, resolution = 0.33 Hz
before peak at 166.7 Hz | 1x 0.81 | blade pass 2.99 | 1x/blade 0.27
after peak at 83.3 Hz | 1x 6.02 | blade pass 2.97 | 1x/blade 2.03
ก่อนลงจอดแรง ยอดสูงสุดอยู่ที่ความถี่ใบพัดผ่านตามปกติ หลังลงจอด ยอดที่ สูงขึ้นหลายเท่าจนกลายเป็นยอดสูงสุด ขณะที่ความถี่ใบพัดผ่านแทบไม่เปลี่ยน รูปแบบนี้ชี้ไปที่ความไม่สมดุลของชิ้นที่หมุน (ใบพัดบิ่นหรือเพลาคด) มากกว่าฐานกันสั่นหลวม ซึ่งมักทำให้การสั่นเพิ่มทุกความถี่ ในข้อมูลจริง มอเตอร์ทั้งสี่หมุนไม่เท่ากันเล็กน้อย ยอดจึงกว้างกว่านี้ และต้องหาว่าเป็นมอเตอร์ตัวใดด้วยการตรวจชิ้นส่วน
เทียบเซนเซอร์ที่ซ้ำกัน
ตัวควบคุมการบินรุ่นใหม่มี IMU สองถึงสามชุด และหลายลำมีเข็มทิศมากกว่าหนึ่งตัว ArduPilot เทียบเซนเซอร์ที่ซ้ำกันในการตรวจก่อนติดเครื่อง (pre-arm) เช่น แจ้ง “Gyros inconsistent” เมื่อ gyro สองชุดต่างกันตั้งแต่ 5 deg/s และ “Accels inconsistent” เมื่อแอกเซเลอโรมิเตอร์ต่างกัน 0.75 m/s² ช่างซ่อมบำรุงใช้หลักเดียวกันได้ละเอียดกว่านี้ เพื่อจับความผิดปกติที่ยังไม่ถึงเกณฑ์ห้ามบิน ถ้าเซนเซอร์สามตัววัดสิ่งเดียวกัน ตัวที่ต่างจากอีกสองตัวมากคือผู้ต้องสงสัยแรก แต่ถ้ามีเพียงสองตัวแล้วไม่ตรงกัน บอกได้เพียงว่ามีตัวหนึ่งผิด ต้องหาหลักฐานอื่นเพิ่ม
ตัวอย่างที่ 2 หา IMU ที่ผิดปกติจากค่ามัธยฐาน
อัตราหมุนแกน Z (deg/s) จาก IMU สามชุดขณะวางนิ่งบนพื้น 5 ช่วงเวลา ทีมกำหนดว่าต่างจากค่ามัธยฐานเกิน 1.0 deg/s ถือว่าผิดปกติ (ค่าจำลอง)
import statistics as st
gyro_z = { # deg/s ขณะวางนิ่ง
"IMU0": [0.05, -0.02, 0.03, 0.01, -0.04],
"IMU1": [0.02, 0.01, -0.03, 0.04, 0.00],
"IMU2": [1.62, 1.58, 1.71, 1.66, 1.60],
}
LIMIT = 1.0
n = len(next(iter(gyro_z.values())))
for k in range(n):
med = st.median(v[k] for v in gyro_z.values())
bad = [name for name, v in gyro_z.items() if abs(v[k] - med) > LIMIT]
print(f"sample {k}: median {med:+.2f} deg/s, outliers {bad or 'none'}")
bias = {name: st.mean(v) for name, v in gyro_z.items()}
print("mean while stationary:", {k: round(v, 2) for k, v in bias.items()})
sample 0: median +0.05 deg/s, outliers ['IMU2']
sample 1: median +0.01 deg/s, outliers ['IMU2']
sample 2: median +0.03 deg/s, outliers ['IMU2']
sample 3: median +0.04 deg/s, outliers ['IMU2']
sample 4: median +0.00 deg/s, outliers ['IMU2']
mean while stationary: {'IMU0': 0.01, 'IMU1': 0.01, 'IMU2': 1.63}
IMU2 มีค่าเบี่ยงคงที่ราว 1.6 deg/s ทั้งที่โดรนวางนิ่ง ขณะที่อีกสองชุดใกล้ศูนย์ ค่าต่าง 1.6 deg/s ยังไม่ถึงเกณฑ์ 5 deg/s ของ pre-arm จึงติดเครื่องบินได้ตามปกติ การผ่าน pre-arm จึงไม่ได้แปลว่าเซนเซอร์สมบูรณ์ ผลนี้บอกว่า IMU2 ผิด แต่ยังไม่บอกสาเหตุ อาจเป็นการสอบเทียบเก่า อุณหภูมิ หรือตัวเซนเซอร์เสียหายจากแรงกระแทก ต้องสอบเทียบใหม่แล้วทดสอบซ้ำ ถ้ายังผิดจึงเปลี่ยนบอร์ดหรือปิดใช้งาน IMU นั้นตามคู่มือ
เขียนผลวินิจฉัย
ผลวินิจฉัยที่ดีแยกสามส่วนชัดเจน: หลักฐาน (ข้อมูลใน log การตรวจด้วยตา ผลวัด) ข้อสรุป (สมมติฐานที่หลักฐานสนับสนุนมากที่สุด และสมมติฐานที่ตัดออกไปพร้อมเหตุผล) และ การยืนยัน (การทดสอบหลังซ่อมที่จะพิสูจน์ว่าแก้ถูกจุด ซึ่งจะเรียนในโมดูล 4) ห้ามเขียนข้อสันนิษฐานเหมือนเป็นข้อเท็จจริง
ปฏิบัติการประจำโมดูล
ปฏิบัติการ: วินิจฉัยจาก log จริง
- ดาวน์โหลด log ขณะลอยตัวของโดรนฝึก ใช้ ArduPilot WebTools (FilterReview) ดูสเปกตรัมการสั่น
- ติดเทปถ่วงเล็ก ๆ ที่ปลายใบพัดหนึ่งใบภายใต้การกำกับของอาจารย์ บินลอยตัวซ้ำ แล้วเทียบสเปกตรัมกับตัวอย่างที่ 1
- ดึงค่า IMU ทุกชุดขณะวางนิ่ง เทียบด้วยตัวอย่างที่ 2
- เขียนผลวินิจฉัยหนึ่งหน้าแยกหลักฐาน ข้อสรุป และการยืนยัน
- ถอดเทปถ่วงออก บินยืนยันว่าสเปกตรัมกลับเป็นเหมือนเดิม
ข้อผิดพลาดที่พบบ่อย
ระวัง
- เชื่อสมมติฐานแรกที่นึกออก
- ดูแค่ขนาดการสั่นรวม ไม่ดูว่าอยู่ที่ความถี่ใด
- ใช้ข้อมูลสั้นเกินไป จนความละเอียดความถี่ไม่พอแยกยอด
- ตัดสินจากเซนเซอร์สองตัวที่ไม่ตรงกัน ว่าตัวใดผิด โดยไม่มีหลักฐานเพิ่ม
- เขียนข้อสันนิษฐานเหมือนข้อเท็จจริง
สรุป
- ความไม่สมดุลของชิ้นที่หมุนเด่นที่ความถี่ ส่วนความถี่ใบพัดผ่านมีอยู่ในโดรนปกติ
- ความละเอียดความถี่ของ FFT เท่ากับ ข้อมูลยาวขึ้นแยกยอดได้ละเอียดขึ้น
- เซนเซอร์สามตัวให้ค่ามัธยฐานที่ใช้หาตัวผิดปกติได้ สองตัวบอกได้แค่ว่ามีตัวผิด
- ผลวินิจฉัยต้องแยกหลักฐาน ข้อสรุป และการยืนยัน
แบบฝึกตรวจความเข้าใจ
- มอเตอร์ 6,600 rpm ความถี่ เท่าใด
- ใบพัด 3 ใบที่ 6,600 rpm ความถี่ใบพัดผ่านเท่าใด
- ต้องการความละเอียดความถี่ 0.25 Hz ต้องเก็บข้อมูลนานเท่าใด
- IMU สามชุดอ่าน 0.02, 0.05 และ 1.40 deg/s ตัวใดผิดปกติเมื่อเกณฑ์คือ 1.0 deg/s จากค่ามัธยฐาน
- ทำไม log จึงไม่ใช่ความจริงทั้งหมด
เฉลย
- Hz
- Hz
- วินาที
- ตัวที่อ่าน 1.40 deg/s เพราะต่างจากค่ามัธยฐาน 0.05 ถึง 1.35 deg/s
- log บันทึกค่าที่เซนเซอร์วัดและระบบคำนวณ ซึ่งอาจผิดจากการวัด สายเชื่อมต่อ หรือระบบย่อยอื่น
สรุปสูตรสำคัญ
| ความถี่การหมุนของมอเตอร์และความถี่ใบพัดผ่าน | |
| ความละเอียดความถี่ของ FFT |
แหล่งอ้างอิงหลัก
- ArduPilot Dev Team. Managing gyro noise with the dynamic harmonic notch filters. ArduPilot Copter documentation. link
- ArduPilot Dev Team. In-flight FFT. ArduPilot Copter documentation. link
- ArduPilot Dev Team. Measuring vibration. ArduPilot Copter documentation. link
- ArduPilot Dev Team. Onboard message log messages. ArduPilot Copter documentation. link
- ArduPilot Dev Team. Pre-arm safety checks. ArduPilot Copter documentation. link
อ่านเพิ่มเติม
ศึกษาหน่วยความรู้ที่กำหนดล่วงหน้า ดูสื่อประกอบ และทำ quiz ประจำโมดูล
วินิจฉัยจากอาการและ log
วิเคราะห์ filter จาก flight log
ArduPilot WebTools
ในชั้นเรียน / ภาคสนาม
ปฏิบัติการในห้องแล็บหรือภาคสนามตามใบงาน พร้อม checklist ความปลอดภัย
หลักฐานการเรียนรู้: ใบงานที่ผ่านการตรวจและผล quiz