# เฉลยพร้อมเหตุผล: PID / timing / STOP_SIM

อ้างผล PC สังเคราะห์เดิม protocol1.0.0 แต่ละกรณี601แถว ใช้ evidence.csv คัด20แถวเพื่อหาจุดสำคัญ ผลรวมต้องอ่าน summaries.json/CSVเต็ม ไม่ importหรือรัน flight firmware รอบนี้

## C1 · หน่วยก่อนตีความคำสั่ง

angle deg; rate deg/s; u deg/s²; integral deg·s สมการสอนคือ rate_next=rate+(u−0.8×rate)×dt แล้ว angle_next=angle+rate_next×dt; damping0.8มีหน่วยs⁻¹ u จึงเป็น angular-acceleration input ของแบบจำลอง ไม่ใช่ ESC/RPM/PWM คำสั่งในระบบจริงต้องอ่าน schema/วงควบคุม/การจัดสรรแยก

## C2 · deadline กับคาบจริง

| overload tick | scheduled_ms | start_ms | finish_ms | deadline_ms | release_delay_ms | dt_ms | missed_deadline |
|---|---|---|---|---|---|---|---|
|40|400|400|412|410|0|10|1|
|41|410|412|418|420|2|12|0|
|42|420|420|426|430|0|8|0|

deadline=scheduled+10; missed เมื่อfinish>deadline (จบตรงขอบยังไม่missed) งานtick41รอtick40จบ จึงstart412; dt=412−400=12 ms รอบถัดไปstart420จึงdt=8 ms ไม่ใช่ทุกtickใช้dt10เพียงเพราะตั้งคาบ10 ผลรวมoverload missed15 และdelayสูงสุด2 ms เป็น scheduling ledger ไม่ใช่เวลาที่จับจาก MCU

## C3 · healthy แตะขีดจำกัดได้

tick100 error15°,rate0,integralก่อนหน้า0,dt0.01s: candidate integral0.15 deg·s; P60, candidate I0.15,D0 ทำให้raw_candidate60.15>60 และerrorบวกดันต่อทิศอิ่มตัว จึงhold integralเดิม0; stored I0, u60 deg/s², output_at_limit1, integral_held1 healthyจึงแตะขีดจำกัด1tickและhold1tickได้ ไม่ใช่ว่า healthy ต้องไม่มีflagทุกชนิด

## C4 · saturation และ anti-windup ของโจทย์

tick100 error30°: candidate integral0.3 deg·s, P120,candidate I0.3,D0;raw_candidate120.3>60 จึงhold integral0 และclip u60 ผลทั้งrun: saturation output_limit36/hold36 เทียบhealthy1/1 ค่าจาก CSV เต็มตรงsummary Tick100–135inclusiveอยู่ที่limit;tick136 u58.592635 และhold0 การหยุดสะสมนี้เป็น conditional integration ของโจทย์ ไม่ใช่หลักฐานว่ามี anti-windup ครบทุก flight controller

## C5 · อายุเก่ากับขอบหยุด

sampleสุดท้าย2990 ms;tick310 start3100→age110 ms ยังACTIVE;tick311 start3110→age120 ms เปลี่ยนSTOP_SIM reason=data_age_limit คำนวณ3110−2990=120;หยุดเมื่อage≥120 ไม่ใช่>120 และไม่หยุดทันทีที่sample_fresh=0 (tick300 age10ยังACTIVE) หลังหยุดlatchตลอดrun ตามpolicy ห้ามสรุปการกลับมาทำงานเมื่อข้อมูลสดจากtraceนี้เพราะไม่มีช่วงข้อมูลฟื้นในfixture

## C6 · u=0 ไม่ได้แปลว่ามุม/อัตราเป็นศูนย์

| data-loss tick | angle_deg | rate_deg_s | u_deg_s2 | mode |
|---|---|---|---|---|
|311|17.297878|1.642832|0|STOP_SIM|
|312|17.314175|1.629689|0|STOP_SIM|
|600|19.135055|0.161238|0|STOP_SIM|

plantยังมีrateและdamping:หลังu=0 rateค่อยลดและangleยังเปลี่ยน การเคลื่อนที่ก่อนtick311ใช้commandก่อนหน้า ส่วนcommand0ใช้ในช่วงถัดไป ตัวเลขนี้เป็นstateแบบจำลอง ไม่ใช่ผลหยุดมอเตอร์/ระยะหยุดโดรนจริง

## C7 · แยก counter และความหมายคอลัมน์ตาม mode

STOP_SIMมี290tick (311..600inclusive);integral_held291เพราะมีACTIVE tick100ที่holdก่อนหน้ารวมด้วย ในSTOP_SIMโค้ดคง integral10.086022 deg·s และบันทึกi_deg_s2=10.086022 แต่force u0 โดยไม่บวกP/I/Dอีก ดังนั้นอย่าคำนวณu=P+I+Dทุกแถวโดยไม่อ่านmode/โค้ดนิยาม log ถ้าเห็นheldก็ยังสรุปว่าเกิดoutput saturationในแถวนั้นไม่ได้

## C8 · สรุปตามขอบเขต

ยืนยันเหตุจากข้อมูลสังเคราะห์:overload deadline15; saturation limit/hold36; data-lossเปลี่ยนSTOP_SIMที่3110 ms และcommand0ต่อในแบบจำลอง ยังไม่ยืนยัน CPU timing/IRQ latency/noise/actuator/การบินหรือผลผู้เรียนจริง STOP_SIMไม่ใช่failsafe firmware;การอ่านlog ArduCopter SITLเดิมในบทมีfirmwareและprotocolอีกชุด ต้องระบุคนละแหล่ง/clock/trigger และไม่ใช้ค่านี้แทนผลบิน

เทียบโครงสร้างจริงได้จาก [PX4 v1.16 controller diagrams](https://docs.px4.io/v1.16/en/flight_stack/controller_diagrams): มีขอบ integral/output และการกรอง derivative ใน rate controller ส่วน [failsafe configuration](https://docs.px4.io/v1.16/en/config/safety) กำหนดการตอบสนองตามเหตุ/การตั้งค่า อ่านเพื่อแยก flight stack จากสมการสอน ไม่คัด gains/STOP_SIM ไปใช้บิน

## เกณฑ์ตรวจตนเองที่เสนอ

ข้อละ2:คำตอบครบ1+เหตุผล/หน่วย/ขอบเขต1 รวม16 C1ครบ4หน่วย/u;C2ครบ3แถว;C3ครบcandidate/stored I/u;C4ครบค่าtick100/ผลรวม;C5ครบ110/120และขอบ;C6ครบหลักฐาน3tick/plant;C7ครบ291เทียบ290/ความหมายi;C8ครบหลักฐานและสิ่งที่ยังไม่พิสูจน์ คะแนนใช้เลือกทบทวน ไม่ใช่เกณฑ์ผ่านหรือใบรับรอง
